Commit 285d9b64 authored by Wayne Stambaugh's avatar Wayne Stambaugh

Major component library ojbect editing code refactor.

* All library component object editing is now performed with the ojbect
  except LIB_PIN (coming soon).
* Added TRANFORM class to handle coordinate transforms.
* Remove old transform matrix functions.
* More file renaming to align them with the other component library
  object file names.
* Fix hot key bugs in library editor to disable edit keys while an item
  is being edited.
* Fixed bug when cancelling rotation of text and field objects while
  being moved.
parent 4cdc2c50
...@@ -14,13 +14,11 @@ set(EESCHEMA_SRCS ...@@ -14,13 +14,11 @@ set(EESCHEMA_SRCS
build_BOM.cpp build_BOM.cpp
busentry.cpp busentry.cpp
bus-wire-junction.cpp bus-wire-junction.cpp
class_BodyItem_Text.cpp
class_drawsheet.cpp class_drawsheet.cpp
class_drawsheetpath.cpp class_drawsheetpath.cpp
class_drc_erc_item.cpp class_drc_erc_item.cpp
class_hierarchical_PIN_sheet.cpp class_hierarchical_PIN_sheet.cpp
class_libentry.cpp class_libentry.cpp
class_libentry_fields.cpp
class_library.cpp class_library.cpp
class_marker_sch.cpp class_marker_sch.cpp
class_netlist_object.cpp class_netlist_object.cpp
...@@ -77,7 +75,6 @@ set(EESCHEMA_SRCS ...@@ -77,7 +75,6 @@ set(EESCHEMA_SRCS
edit_component_in_schematic.cpp edit_component_in_schematic.cpp
edit_label.cpp edit_label.cpp
eelayer.cpp eelayer.cpp
eelibs_draw_components.cpp
eelibs_read_libraryfiles.cpp eelibs_read_libraryfiles.cpp
eeredraw.cpp eeredraw.cpp
eeschema.cpp eeschema.cpp
...@@ -101,8 +98,10 @@ set(EESCHEMA_SRCS ...@@ -101,8 +98,10 @@ set(EESCHEMA_SRCS
lib_circle.cpp lib_circle.cpp
lib_draw_item.cpp lib_draw_item.cpp
lib_export.cpp lib_export.cpp
lib_field.cpp
lib_polyline.cpp lib_polyline.cpp
lib_rectangle.cpp lib_rectangle.cpp
lib_text.cpp
libfield.cpp libfield.cpp
load_one_schematic_file.cpp load_one_schematic_file.cpp
locate.cpp locate.cpp
...@@ -135,6 +134,7 @@ set(EESCHEMA_SRCS ...@@ -135,6 +134,7 @@ set(EESCHEMA_SRCS
tool_lib.cpp tool_lib.cpp
tool_sch.cpp tool_sch.cpp
tool_viewlib.cpp tool_viewlib.cpp
transform.cpp
viewlib_frame.cpp viewlib_frame.cpp
viewlibs.cpp) viewlibs.cpp)
......
...@@ -906,7 +906,8 @@ static LIB_PIN* GetNextPinPosition( SCH_COMPONENT* aDrawLibItem, ...@@ -906,7 +906,8 @@ static LIB_PIN* GetNextPinPosition( SCH_COMPONENT* aDrawLibItem,
bool aSearchFirst ) bool aSearchFirst )
{ {
static LIB_COMPONENT* Entry; static LIB_COMPONENT* Entry;
static int Multi, convert, TransMat[2][2]; static int Multi, convert;
TRANSFORM transform;
static wxPoint CmpPosition; static wxPoint CmpPosition;
static LIB_PIN* Pin; static LIB_PIN* Pin;
...@@ -921,7 +922,7 @@ static LIB_PIN* GetNextPinPosition( SCH_COMPONENT* aDrawLibItem, ...@@ -921,7 +922,7 @@ static LIB_PIN* GetNextPinPosition( SCH_COMPONENT* aDrawLibItem,
Multi = aDrawLibItem->m_Multi; Multi = aDrawLibItem->m_Multi;
convert = aDrawLibItem->m_Convert; convert = aDrawLibItem->m_Convert;
CmpPosition = aDrawLibItem->m_Pos; CmpPosition = aDrawLibItem->m_Pos;
memcpy( TransMat, aDrawLibItem->m_Transform, sizeof(TransMat) ); transform = aDrawLibItem->m_Transform;
} }
else else
Pin = Entry->GetNextPin( Pin ); Pin = Entry->GetNextPin( Pin );
...@@ -938,7 +939,7 @@ static LIB_PIN* GetNextPinPosition( SCH_COMPONENT* aDrawLibItem, ...@@ -938,7 +939,7 @@ static LIB_PIN* GetNextPinPosition( SCH_COMPONENT* aDrawLibItem,
/* Calculate the pin position (according to the component orientation) /* Calculate the pin position (according to the component orientation)
*/ */
aPosition = TransformCoordinate( TransMat, Pin->m_Pos ) + CmpPosition; aPosition = DefaultTransform.TransformCoordinate( Pin->m_Pos ) + CmpPosition;
return Pin; return Pin;
} }
......
...@@ -16,8 +16,7 @@ ...@@ -16,8 +16,7 @@
#include "libeditframe.h" #include "libeditframe.h"
static void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC, static void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
bool erase );
/* /*
...@@ -102,8 +101,8 @@ int WinEDA_LibeditFrame::HandleBlockEnd( wxDC* DC ) ...@@ -102,8 +101,8 @@ int WinEDA_LibeditFrame::HandleBlockEnd( wxDC* DC )
case BLOCK_COPY: /* Copy */ case BLOCK_COPY: /* Copy */
if ( m_component ) if ( m_component )
ItemCount = m_component->SelectItems( GetScreen()->m_BlockLocate, ItemCount = m_component->SelectItems( GetScreen()->m_BlockLocate,
m_unit, m_convert, m_unit, m_convert,
g_EditPinByPinIsOn ); g_EditPinByPinIsOn );
if( ItemCount ) if( ItemCount )
{ {
MustDoPlace = 1; MustDoPlace = 1;
...@@ -127,8 +126,8 @@ int WinEDA_LibeditFrame::HandleBlockEnd( wxDC* DC ) ...@@ -127,8 +126,8 @@ int WinEDA_LibeditFrame::HandleBlockEnd( wxDC* DC )
case BLOCK_DELETE: /* Delete */ case BLOCK_DELETE: /* Delete */
if ( m_component ) if ( m_component )
ItemCount = m_component->SelectItems( GetScreen()->m_BlockLocate, ItemCount = m_component->SelectItems( GetScreen()->m_BlockLocate,
m_unit, m_convert, m_unit, m_convert,
g_EditPinByPinIsOn ); g_EditPinByPinIsOn );
if( ItemCount ) if( ItemCount )
SaveCopyInUndoList( m_component ); SaveCopyInUndoList( m_component );
if ( m_component ) if ( m_component )
...@@ -146,8 +145,8 @@ int WinEDA_LibeditFrame::HandleBlockEnd( wxDC* DC ) ...@@ -146,8 +145,8 @@ int WinEDA_LibeditFrame::HandleBlockEnd( wxDC* DC )
case BLOCK_MIRROR_Y: case BLOCK_MIRROR_Y:
if ( m_component ) if ( m_component )
ItemCount = m_component->SelectItems( GetScreen()->m_BlockLocate, ItemCount = m_component->SelectItems( GetScreen()->m_BlockLocate,
m_unit, m_convert, m_unit, m_convert,
g_EditPinByPinIsOn ); g_EditPinByPinIsOn );
if( ItemCount ) if( ItemCount )
SaveCopyInUndoList( m_component ); SaveCopyInUndoList( m_component );
pt = GetScreen()->m_BlockLocate.Centre(); pt = GetScreen()->m_BlockLocate.Centre();
...@@ -169,7 +168,7 @@ int WinEDA_LibeditFrame::HandleBlockEnd( wxDC* DC ) ...@@ -169,7 +168,7 @@ int WinEDA_LibeditFrame::HandleBlockEnd( wxDC* DC )
if( MustDoPlace <= 0 ) if( MustDoPlace <= 0 )
{ {
if( GetScreen()->m_BlockLocate.m_Command != BLOCK_SELECT_ITEMS_ONLY ) if( GetScreen()->m_BlockLocate.m_Command != BLOCK_SELECT_ITEMS_ONLY )
if ( m_component ) if ( m_component )
m_component->ClearSelectedItems(); m_component->ClearSelectedItems();
...@@ -179,8 +178,7 @@ int WinEDA_LibeditFrame::HandleBlockEnd( wxDC* DC ) ...@@ -179,8 +178,7 @@ int WinEDA_LibeditFrame::HandleBlockEnd( wxDC* DC )
DrawPanel->ManageCurseur = NULL; DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL; DrawPanel->ForceCloseManageCurseur = NULL;
GetScreen()->SetCurItem( NULL ); GetScreen()->SetCurItem( NULL );
SetToolID( m_ID_current_state, DrawPanel->m_PanelDefaultCursor, SetToolID( m_ID_current_state, DrawPanel->m_PanelDefaultCursor, wxEmptyString );
wxEmptyString );
DrawPanel->Refresh( TRUE ); DrawPanel->Refresh( TRUE );
} }
...@@ -269,8 +267,7 @@ void WinEDA_LibeditFrame::HandleBlockPlace( wxDC* DC ) ...@@ -269,8 +267,7 @@ void WinEDA_LibeditFrame::HandleBlockPlace( wxDC* DC )
GetScreen()->SetCurItem( NULL ); GetScreen()->SetCurItem( NULL );
DrawPanel->Refresh( TRUE ); DrawPanel->Refresh( TRUE );
SetToolID( m_ID_current_state, DrawPanel->m_PanelDefaultCursor, SetToolID( m_ID_current_state, DrawPanel->m_PanelDefaultCursor, wxEmptyString );
wxEmptyString );
} }
...@@ -298,25 +295,19 @@ void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ) ...@@ -298,25 +295,19 @@ void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
if( erase ) if( erase )
{ {
PtBlock->Draw( panel, DC, PtBlock->m_MoveVector, g_XorMode, PtBlock->Draw( panel, DC, PtBlock->m_MoveVector, g_XorMode, PtBlock->m_Color );
PtBlock->m_Color );
component->Draw( panel, DC, PtBlock->m_MoveVector, unit, convert, component->Draw( panel, DC, PtBlock->m_MoveVector, unit, convert,
g_XorMode, -1, DefaultTransformMatrix, g_XorMode, -1, DefaultTransform, true, true, true );
true, true, true );
} }
/* Repaint new view */ /* Repaint new view */
PtBlock->m_MoveVector.x = PtBlock->m_MoveVector.x = screen->m_Curseur.x - PtBlock->m_BlockLastCursorPosition.x;
screen->m_Curseur.x - PtBlock->m_BlockLastCursorPosition.x; PtBlock->m_MoveVector.y = screen->m_Curseur.y - PtBlock->m_BlockLastCursorPosition.y;
PtBlock->m_MoveVector.y =
screen->m_Curseur.y - PtBlock->m_BlockLastCursorPosition.y;
GRSetDrawMode( DC, g_XorMode ); GRSetDrawMode( DC, g_XorMode );
PtBlock->Draw( panel, DC, PtBlock->m_MoveVector, g_XorMode, PtBlock->Draw( panel, DC, PtBlock->m_MoveVector, g_XorMode, PtBlock->m_Color );
PtBlock->m_Color );
component->Draw( panel, DC, PtBlock->m_MoveVector, unit, convert, component->Draw( panel, DC, PtBlock->m_MoveVector, unit, convert,
g_XorMode, -1, DefaultTransformMatrix, g_XorMode, -1, DefaultTransform, true, true, true );
true, true, true );
} }
...@@ -293,12 +293,9 @@ wxString LIB_COMPONENT::ReturnSubReference( int aUnit ) ...@@ -293,12 +293,9 @@ wxString LIB_COMPONENT::ReturnSubReference( int aUnit )
} }
void LIB_COMPONENT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDc, void LIB_COMPONENT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDc, const wxPoint& aOffset, int aMulti,
const wxPoint& aOffset, int aMulti, int aConvert, int aDrawMode, int aColor, const TRANSFORM& aTransform,
int aConvert, int aDrawMode, int aColor, bool aShowPinText, bool aDrawFields, bool aOnlySelected )
const int aTransformMatrix[2][2],
bool aShowPinText, bool aDrawFields,
bool aOnlySelected )
{ {
BASE_SCREEN* screen = aPanel->GetScreen(); BASE_SCREEN* screen = aPanel->GetScreen();
...@@ -336,14 +333,12 @@ void LIB_COMPONENT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDc, ...@@ -336,14 +333,12 @@ void LIB_COMPONENT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDc,
if( drawItem.Type() == COMPONENT_FIELD_DRAW_TYPE ) if( drawItem.Type() == COMPONENT_FIELD_DRAW_TYPE )
{ {
drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode, drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode, NULL, aTransform );
(void*) NULL, aTransformMatrix );
} }
// Now, draw only the background for items with // Now, draw only the background for items with
// m_Fill == FILLED_WITH_BG_BODYCOLOR: // m_Fill == FILLED_WITH_BG_BODYCOLOR:
drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode, drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode, false, aTransform );
(void*) false, aTransformMatrix );
} }
} }
...@@ -368,19 +363,18 @@ void LIB_COMPONENT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDc, ...@@ -368,19 +363,18 @@ void LIB_COMPONENT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDc,
if( drawItem.Type() == COMPONENT_PIN_DRAW_TYPE ) if( drawItem.Type() == COMPONENT_PIN_DRAW_TYPE )
{ {
drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode, drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode, (void*) aShowPinText,
(void*) aShowPinText, aTransformMatrix ); aTransform );
} }
else if( drawItem.Type() == COMPONENT_FIELD_DRAW_TYPE ) else if( drawItem.Type() == COMPONENT_FIELD_DRAW_TYPE )
{ {
drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode, drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode, (void*) NULL, aTransform );
(void*) NULL, aTransformMatrix );
} }
else else
{ {
bool forceNoFill = drawItem.m_Fill == FILLED_WITH_BG_BODYCOLOR; bool forceNoFill = drawItem.m_Fill == FILLED_WITH_BG_BODYCOLOR;
drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode, drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode, (void*) forceNoFill,
(void*) forceNoFill, aTransformMatrix ); aTransform );
} }
} }
...@@ -409,7 +403,7 @@ void LIB_COMPONENT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDc, ...@@ -409,7 +403,7 @@ void LIB_COMPONENT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDc,
void LIB_COMPONENT::Plot( PLOTTER* aPlotter, int aUnit, int aConvert, void LIB_COMPONENT::Plot( PLOTTER* aPlotter, int aUnit, int aConvert,
const wxPoint& aOffset, const int aTransform[2][2] ) const wxPoint& aOffset, const TRANSFORM& aTransform )
{ {
wxASSERT( aPlotter != NULL ); wxASSERT( aPlotter != NULL );
...@@ -451,7 +445,7 @@ from component %s in library %s." ), ...@@ -451,7 +445,7 @@ from component %s in library %s." ),
LIB_DRAW_ITEM_LIST::iterator i; LIB_DRAW_ITEM_LIST::iterator i;
if( aDc != NULL ) if( aDc != NULL )
aItem->Draw( aPanel, aDc, wxPoint( 0, 0 ), -1, g_XorMode, NULL, DefaultTransformMatrix ); aItem->Draw( aPanel, aDc, wxPoint( 0, 0 ), -1, g_XorMode, NULL, DefaultTransform );
for( i = drawings.begin(); i < drawings.end(); i++ ) for( i = drawings.begin(); i < drawings.end(); i++ )
{ {
...@@ -1383,30 +1377,33 @@ LIB_DRAW_ITEM* LIB_COMPONENT::LocateDrawItem( int aUnit, int aConvert, ...@@ -1383,30 +1377,33 @@ LIB_DRAW_ITEM* LIB_COMPONENT::LocateDrawItem( int aUnit, int aConvert,
* Otherwise NULL. * Otherwise NULL.
*/ */
LIB_DRAW_ITEM* LIB_COMPONENT::LocateDrawItem( int aUnit, int aConvert, KICAD_T aType, LIB_DRAW_ITEM* LIB_COMPONENT::LocateDrawItem( int aUnit, int aConvert, KICAD_T aType,
const wxPoint& aPoint, const int aTransform[2][2] ) const wxPoint& aPoint, const TRANSFORM& aTransform )
{ {
/* we use LocateDrawItem( int aUnit, int convert, KICAD_T type, const /* we use LocateDrawItem( int aUnit, int convert, KICAD_T type, const
* wxPoint& pt ) to search items. * wxPoint& pt ) to search items.
* because this function uses DefaultTransformMatrix as orient/mirror matrix * because this function uses DefaultTransformMatrix as orient/mirror matrix
* we temporary copy aTransMat in DefaultTransformMatrix * we temporary copy aTransMat in DefaultTransformMatrix
*/ */
LIB_DRAW_ITEM * item; LIB_DRAW_ITEM* item;
int matrix[2][2]; TRANSFORM transform;
for ( int ii = 0; ii < 2; ii++ ) for ( int ii = 0; ii < 2; ii++ )
{ {
for ( int jj = 0; jj < 2; jj++ ) for ( int jj = 0; jj < 2; jj++ )
{ {
matrix[ii][jj] = aTransform[ii][jj]; transform = DefaultTransform;
EXCHG( matrix[ii][jj], DefaultTransformMatrix[ii][jj] ); DefaultTransform = aTransform;
} }
} }
item = LocateDrawItem( aUnit, aConvert, aType, aPoint ); item = LocateDrawItem( aUnit, aConvert, aType, aPoint );
//Restore matrix //Restore matrix
for ( int ii = 0; ii < 2; ii++ ) for ( int ii = 0; ii < 2; ii++ )
{ {
for ( int jj = 0; jj < 2; jj++ ) for ( int jj = 0; jj < 2; jj++ )
{ {
EXCHG( matrix[ii][jj], DefaultTransformMatrix[ii][jj] ); DefaultTransform = transform;
} }
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#define CLASS_LIBENTRY_H #define CLASS_LIBENTRY_H
#include "lib_draw_item.h" #include "lib_draw_item.h"
#include "class_libentry_fields.h" #include "lib_field.h"
#include <map> #include <map>
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
class CMP_LIBRARY; class CMP_LIBRARY;
class LIB_ALIAS; class LIB_ALIAS;
/** /**
* LIB_ALIAS map sorting. * LIB_ALIAS map sorting.
*/ */
...@@ -312,7 +313,7 @@ public: ...@@ -312,7 +313,7 @@ public:
*/ */
void Draw( WinEDA_DrawPanel* aPanel, wxDC* aDc, const wxPoint& aOffset, void Draw( WinEDA_DrawPanel* aPanel, wxDC* aDc, const wxPoint& aOffset,
int aMulti, int aConvert, int aDrawMode, int aColor = -1, int aMulti, int aConvert, int aDrawMode, int aColor = -1,
const int aTransform[2][2] = DefaultTransformMatrix, const TRANSFORM& aTransform = DefaultTransform,
bool aShowPinText = true, bool aDrawFields = true, bool aShowPinText = true, bool aDrawFields = true,
bool aOnlySelected = false ); bool aOnlySelected = false );
...@@ -325,7 +326,7 @@ public: ...@@ -325,7 +326,7 @@ public:
* @param aTransform - Component plot transform matrix. * @param aTransform - Component plot transform matrix.
*/ */
void Plot( PLOTTER* aPlotter, int aUnit, int aConvert, const wxPoint& aOffset, void Plot( PLOTTER* aPlotter, int aUnit, int aConvert, const wxPoint& aOffset,
const int aTransform[2][2] ); const TRANSFORM& aTransform );
/** /**
* Add a new draw \a aItem to the draw object list. * Add a new draw \a aItem to the draw object list.
...@@ -493,7 +494,7 @@ public: ...@@ -493,7 +494,7 @@ public:
* @return The draw object if found. Otherwise NULL. * @return The draw object if found. Otherwise NULL.
*/ */
LIB_DRAW_ITEM* LocateDrawItem( int aUnit, int aConvert, KICAD_T aType, LIB_DRAW_ITEM* LocateDrawItem( int aUnit, int aConvert, KICAD_T aType,
const wxPoint& aPoint, const int aTransfrom[2][2] ); const wxPoint& aPoint, const TRANSFORM& aTransfrom );
/** /**
* Return a reference to the draw item list. * Return a reference to the draw item list.
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "libeditframe.h" #include "libeditframe.h"
#include "class_libentry.h" #include "class_libentry.h"
#include "class_pin.h" #include "class_pin.h"
#include "transform.h"
#include "bitmaps.h" #include "bitmaps.h"
...@@ -536,7 +537,7 @@ bool LIB_PIN::HitTest( const wxPoint& aRefPos ) ...@@ -536,7 +537,7 @@ bool LIB_PIN::HitTest( const wxPoint& aRefPos )
if( mindist < 3 ) if( mindist < 3 )
mindist = 3; // = 3 mils mindist = 3; // = 3 mils
return HitTest( aRefPos, mindist, DefaultTransformMatrix ); return HitTest( aRefPos, mindist, DefaultTransform );
} }
/** Function HitTest /** Function HitTest
...@@ -545,11 +546,10 @@ bool LIB_PIN::HitTest( const wxPoint& aRefPos ) ...@@ -545,11 +546,10 @@ bool LIB_PIN::HitTest( const wxPoint& aRefPos )
* @param aThreshold = max distance to a segment * @param aThreshold = max distance to a segment
* @param aTransMat = the transform matrix * @param aTransMat = the transform matrix
*/ */
bool LIB_PIN::HitTest( wxPoint aRefPos, int aThreshold, bool LIB_PIN::HitTest( wxPoint aRefPos, int aThreshold, const TRANSFORM& aTransform )
const int aTransMat[2][2] )
{ {
wxPoint pinPos = TransformCoordinate( aTransMat, m_Pos ); wxPoint pinPos = aTransform.TransformCoordinate( m_Pos );
wxPoint pinEnd = TransformCoordinate( aTransMat, ReturnPinEndPoint() ); wxPoint pinEnd = aTransform.TransformCoordinate( ReturnPinEndPoint() );
return TestSegmentHit( aRefPos, pinPos, pinEnd, aThreshold ); return TestSegmentHit( aRefPos, pinPos, pinEnd, aThreshold );
} }
...@@ -791,18 +791,17 @@ int LIB_PIN::GetPenSize() ...@@ -791,18 +791,17 @@ int LIB_PIN::GetPenSize()
} }
void LIB_PIN::Draw( WinEDA_DrawPanel* aPanel, void LIB_PIN::drawGraphic( WinEDA_DrawPanel* aPanel,
wxDC* aDC, wxDC* aDC,
const wxPoint& aOffset, const wxPoint& aOffset,
int aColor, int aColor,
int aDrawMode, int aDrawMode,
void* aData, void* aData,
const int aTransformMatrix[2][2] ) const TRANSFORM& aTransform )
{ {
// Invisible pins are only drawn on request. In libedit they are drawn // Invisible pins are only drawn on request. In libedit they are drawn
// in g_InvisibleItemColor because we must see them. // in g_InvisibleItemColor because we must see them.
WinEDA_SchematicFrame* frame = WinEDA_SchematicFrame* frame = (WinEDA_SchematicFrame*) wxGetApp().GetTopWindow();
(WinEDA_SchematicFrame*) wxGetApp().GetTopWindow();
if( ( m_Attributs & PINNOTDRAW ) ) if( ( m_Attributs & PINNOTDRAW ) )
{ {
...@@ -819,10 +818,10 @@ void LIB_PIN::Draw( WinEDA_DrawPanel* aPanel, ...@@ -819,10 +818,10 @@ void LIB_PIN::Draw( WinEDA_DrawPanel* aPanel,
DrawPinText = false; DrawPinText = false;
/* Calculate pin orient taking in account the component orientation. */ /* Calculate pin orient taking in account the component orientation. */
int orient = ReturnPinDrawOrient( aTransformMatrix ); int orient = ReturnPinDrawOrient( aTransform );
/* Calculate the pin position */ /* Calculate the pin position */
wxPoint pos1 = TransformCoordinate( aTransformMatrix, m_Pos ) + aOffset; wxPoint pos1 = aTransform.TransformCoordinate( m_Pos ) + aOffset;
/* Drawing from the pin and the special symbol combination */ /* Drawing from the pin and the special symbol combination */
DrawPinSymbol( aPanel, aDC, pos1, orient, aDrawMode, aColor ); DrawPinSymbol( aPanel, aDC, pos1, orient, aDrawMode, aColor );
...@@ -1476,7 +1475,7 @@ wxPoint LIB_PIN::ReturnPinEndPoint() ...@@ -1476,7 +1475,7 @@ wxPoint LIB_PIN::ReturnPinEndPoint()
* according to its orientation and the matrix transform (rot, mirror) TransMat * according to its orientation and the matrix transform (rot, mirror) TransMat
* @param TransMat = transform matrix * @param TransMat = transform matrix
*/ */
int LIB_PIN::ReturnPinDrawOrient( const int TransMat[2][2] ) int LIB_PIN::ReturnPinDrawOrient( const TRANSFORM& aTransform )
{ {
int orient; int orient;
wxPoint end; // position of a end pin starting at 0,0 according to its orientation, lenght = 1 wxPoint end; // position of a end pin starting at 0,0 according to its orientation, lenght = 1
...@@ -1497,7 +1496,7 @@ int LIB_PIN::ReturnPinDrawOrient( const int TransMat[2][2] ) ...@@ -1497,7 +1496,7 @@ int LIB_PIN::ReturnPinDrawOrient( const int TransMat[2][2] )
} }
// = pos of end point, according to the component orientation // = pos of end point, according to the component orientation
end = TransformCoordinate( TransMat, end ); end = aTransform.TransformCoordinate( end );
orient = PIN_UP; orient = PIN_UP;
if( end.x == 0 ) if( end.x == 0 )
{ {
...@@ -1653,14 +1652,14 @@ void LIB_PIN::DoMirrorHorizontal( const wxPoint& center ) ...@@ -1653,14 +1652,14 @@ void LIB_PIN::DoMirrorHorizontal( const wxPoint& center )
void LIB_PIN::DoPlot( PLOTTER* plotter, const wxPoint& offset, bool fill, void LIB_PIN::DoPlot( PLOTTER* plotter, const wxPoint& offset, bool fill,
const int transform[2][2] ) const TRANSFORM& aTransform )
{ {
if( m_Attributs & PINNOTDRAW ) if( m_Attributs & PINNOTDRAW )
return; return;
int orient = ReturnPinDrawOrient( transform ); int orient = ReturnPinDrawOrient( aTransform );
wxPoint pos = TransformCoordinate( transform, m_Pos ) + offset; wxPoint pos = aTransform.TransformCoordinate( m_Pos ) + offset;
plotter->set_current_line_width( GetPenSize() ); plotter->set_current_line_width( GetPenSize() );
PlotPinSymbol( plotter, pos, m_PinLen, orient, m_PinShape ); PlotPinSymbol( plotter, pos, m_PinLen, orient, m_PinShape );
......
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
#include "lib_draw_item.h" #include "lib_draw_item.h"
#define TARGET_PIN_DIAM 12 /* Circle diameter drawn at the active end of
* pins */ #define TARGET_PIN_DIAM 12 /* Circle diameter drawn at the active end of pins */
#define DEFAULT_TEXT_SIZE 50 /* Default size for field texts */ #define DEFAULT_TEXT_SIZE 50 /* Default size for field texts */
#define PART_NAME_LEN 15 /* Maximum length of part name. */ #define PART_NAME_LEN 15 /* Maximum length of part name. */
...@@ -80,6 +80,12 @@ enum DrawPinOrient { ...@@ -80,6 +80,12 @@ enum DrawPinOrient {
class LIB_PIN : public LIB_DRAW_ITEM class LIB_PIN : public LIB_DRAW_ITEM
{ {
/**
* Draw the pin.
*/
void drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOffset,
int aColor, int aDrawMode, void* aData, const TRANSFORM& aTransform );
public: public:
int m_PinLen; /* Pin length */ int m_PinLen; /* Pin length */
int m_Orient; /* Pin orientation (Up, Down, Left, Right) */ int m_Orient; /* Pin orientation (Up, Down, Left, Right) */
...@@ -106,7 +112,7 @@ public: ...@@ -106,7 +112,7 @@ public:
int m_Width; /* Line width */ int m_Width; /* Line width */
public: public:
LIB_PIN(LIB_COMPONENT * aParent); LIB_PIN( LIB_COMPONENT * aParent );
LIB_PIN( const LIB_PIN& aPin ); LIB_PIN( const LIB_PIN& aPin );
~LIB_PIN() { } ~LIB_PIN() { }
...@@ -148,13 +154,13 @@ public: ...@@ -148,13 +154,13 @@ public:
* @param aTransMat - the transform matrix * @param aTransMat - the transform matrix
* @return - true if the point aPosRef is near this object * @return - true if the point aPosRef is near this object
*/ */
virtual bool HitTest( wxPoint aPosRef, int aThreshold, const int aTransMat[2][2] ); virtual bool HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform );
virtual void DisplayInfo( WinEDA_DrawFrame* frame ); virtual void DisplayInfo( WinEDA_DrawFrame* frame );
virtual EDA_Rect GetBoundingBox(); virtual EDA_Rect GetBoundingBox();
wxPoint ReturnPinEndPoint(); wxPoint ReturnPinEndPoint();
int ReturnPinDrawOrient( const int TransMat[2][2] ); int ReturnPinDrawOrient( const TRANSFORM& aTransform );
/** /**
* Fill a string buffer with pin number. * Fill a string buffer with pin number.
...@@ -194,7 +200,7 @@ public: ...@@ -194,7 +200,7 @@ public:
void SetName( const wxString& aName ); void SetName( const wxString& aName );
/** /**
* Set the /a aSize of the pin name text. * Set the \a aSize of the pin name text.
* *
* This will also update the text size of the name of the pins marked * This will also update the text size of the name of the pins marked
* by EnableEditMode(). * by EnableEditMode().
...@@ -323,9 +329,6 @@ public: ...@@ -323,9 +329,6 @@ public:
*/ */
virtual int GetPenSize(); virtual int GetPenSize();
void Draw( WinEDA_DrawPanel * aPanel, wxDC * aDC, const wxPoint &aOffset,
int aColor, int aDrawMode, void* aData, const int aTransformMatrix[2][2] );
void DrawPinSymbol( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aPosition, void DrawPinSymbol( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aPosition,
int aOrientation, int aDrawMode, int aColor = -1 ); int aOrientation, int aDrawMode, int aColor = -1 );
...@@ -438,7 +441,7 @@ protected: ...@@ -438,7 +441,7 @@ protected:
virtual wxPoint DoGetPosition() { return m_Pos; } virtual wxPoint DoGetPosition() { return m_Pos; }
virtual void DoMirrorHorizontal( const wxPoint& aCenter ); virtual void DoMirrorHorizontal( const wxPoint& aCenter );
virtual void DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, virtual void DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
const int aTransform[2][2] ); const TRANSFORM& aTransform );
virtual int DoGetWidth() { return m_Width; } virtual int DoGetWidth() { return m_Width; }
virtual void DoSetWidth( int aWidth ) { m_Width = aWidth; } virtual void DoSetWidth( int aWidth ) { m_Width = aWidth; }
}; };
......
...@@ -98,7 +98,7 @@ void SCH_FIELD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, ...@@ -98,7 +98,7 @@ void SCH_FIELD::Draw( WinEDA_DrawPanel* panel, wxDC* DC,
/* Calculate the text orientation, according to the component /* Calculate the text orientation, according to the component
* orientation/mirror */ * orientation/mirror */
orient = m_Orient; orient = m_Orient;
if( parentComponent->m_Transform[0][1] ) // Rotate component 90 degrees. if( parentComponent->m_Transform.y1 ) // Rotate component 90 degrees.
{ {
if( orient == TEXT_ORIENT_HORIZ ) if( orient == TEXT_ORIENT_HORIZ )
orient = TEXT_ORIENT_VERT; orient = TEXT_ORIENT_VERT;
...@@ -245,11 +245,11 @@ EDA_Rect SCH_FIELD::GetBoundaryBox() const ...@@ -245,11 +245,11 @@ EDA_Rect SCH_FIELD::GetBoundaryBox() const
hjustify = m_HJustify; hjustify = m_HJustify;
vjustify = m_VJustify; vjustify = m_VJustify;
pos2 = pos + TransformCoordinate( parentComponent->m_Transform, pos1 ); pos2 = pos + parentComponent->m_Transform.TransformCoordinate( pos1 );
/* Calculate the text orientation, according to the component /* Calculate the text orientation, according to the component
* orientation/mirror */ * orientation/mirror */
if( parentComponent->m_Transform[0][1] ) if( parentComponent->m_Transform.y1 )
{ {
if( orient == TEXT_ORIENT_HORIZ ) if( orient == TEXT_ORIENT_HORIZ )
orient = TEXT_ORIENT_VERT; orient = TEXT_ORIENT_VERT;
...@@ -259,20 +259,20 @@ EDA_Rect SCH_FIELD::GetBoundaryBox() const ...@@ -259,20 +259,20 @@ EDA_Rect SCH_FIELD::GetBoundaryBox() const
/* Calculate the text justification, according to the component /* Calculate the text justification, according to the component
* orientation/mirror */ * orientation/mirror */
if( parentComponent->m_Transform[0][1] ) if( parentComponent->m_Transform.y1 )
{ {
/* is it mirrored (for text justify)*/ /* is it mirrored (for text justify)*/
EXCHG( hjustify, vjustify ); EXCHG( hjustify, vjustify );
if( parentComponent->m_Transform[1][0] < 0 ) if( parentComponent->m_Transform.x2 < 0 )
NEGATE( vjustify ); NEGATE( vjustify );
if( parentComponent->m_Transform[0][1] > 0 ) if( parentComponent->m_Transform.y1 > 0 )
NEGATE( hjustify ); NEGATE( hjustify );
} }
else /* component horizontal: is it mirrored (for text justify)*/ else /* component horizontal: is it mirrored (for text justify)*/
{ {
if( parentComponent->m_Transform[0][0] < 0 ) if( parentComponent->m_Transform.x1 < 0 )
NEGATE( hjustify ); NEGATE( hjustify );
if( parentComponent->m_Transform[1][1] > 0 ) if( parentComponent->m_Transform.y2 > 0 )
NEGATE( vjustify ); NEGATE( vjustify );
} }
......
...@@ -151,10 +151,7 @@ void SCH_COMPONENT::Init( const wxPoint& pos ) ...@@ -151,10 +151,7 @@ void SCH_COMPONENT::Init( const wxPoint& pos )
m_Convert = 0; // De Morgan Handling m_Convert = 0; // De Morgan Handling
// The rotation/mirror transformation matrix. pos normal // The rotation/mirror transformation matrix. pos normal
m_Transform[0][0] = 1; m_Transform = TRANSFORM();
m_Transform[0][1] = 0;
m_Transform[1][0] = 0;
m_Transform[1][1] = -1;
// construct only the mandatory fields, which are the first 4 only. // construct only the mandatory fields, which are the first 4 only.
for( int i = 0; i < MANDATORY_FIELDS; ++i ) for( int i = 0; i < MANDATORY_FIELDS; ++i )
...@@ -578,10 +575,10 @@ EDA_Rect SCH_COMPONENT::GetBoundaryBox() const ...@@ -578,10 +575,10 @@ EDA_Rect SCH_COMPONENT::GetBoundaryBox() const
} }
/* Compute the real Boundary box (rotated, mirrored ...)*/ /* Compute the real Boundary box (rotated, mirrored ...)*/
int x1 = m_Transform[0][0] *x0 + m_Transform[0][1] *y0; int x1 = m_Transform.x1 * x0 + m_Transform.y1 * y0;
int y1 = m_Transform[1][0] *x0 + m_Transform[1][1] *y0; int y1 = m_Transform.x2 * x0 + m_Transform.y2 * y0;
int x2 = m_Transform[0][0] *xm + m_Transform[0][1] *ym; int x2 = m_Transform.x1 * xm + m_Transform.y1 * ym;
int y2 = m_Transform[1][0] *xm + m_Transform[1][1] *ym; int y2 = m_Transform.x2 * xm + m_Transform.y2 * ym;
// H and W must be > 0: // H and W must be > 0:
if( x2 < x1 ) if( x2 < x1 )
...@@ -608,10 +605,10 @@ void SCH_COMPONENT::SwapData( SCH_COMPONENT* copyitem ) ...@@ -608,10 +605,10 @@ void SCH_COMPONENT::SwapData( SCH_COMPONENT* copyitem )
EXCHG( m_Pos, copyitem->m_Pos ); EXCHG( m_Pos, copyitem->m_Pos );
EXCHG( m_Multi, copyitem->m_Multi ); EXCHG( m_Multi, copyitem->m_Multi );
EXCHG( m_Convert, copyitem->m_Convert ); EXCHG( m_Convert, copyitem->m_Convert );
EXCHG( m_Transform[0][0], copyitem->m_Transform[0][0] );
EXCHG( m_Transform[0][1], copyitem->m_Transform[0][1] ); TRANSFORM tmp = m_Transform;
EXCHG( m_Transform[1][0], copyitem->m_Transform[1][0] ); m_Transform = copyitem->m_Transform;
EXCHG( m_Transform[1][1], copyitem->m_Transform[1][1] ); copyitem->m_Transform = tmp;
m_Fields.swap( copyitem->m_Fields ); // std::vector's swap() m_Fields.swap( copyitem->m_Fields ); // std::vector's swap()
...@@ -727,44 +724,44 @@ void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheet ) ...@@ -727,44 +724,44 @@ void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheet )
/*****************************************************************/ /*****************************************************************/
void SCH_COMPONENT::SetOrientation( int aOrientation ) void SCH_COMPONENT::SetOrientation( int aOrientation )
{ {
int TempMat[2][2]; TRANSFORM temp = TRANSFORM();
bool Transform = FALSE; bool Transform = false;
switch( aOrientation ) switch( aOrientation )
{ {
case CMP_ORIENT_0: case CMP_ORIENT_0:
case CMP_NORMAL: /* Position Initiale */ case CMP_NORMAL: /* Position Initiale */
m_Transform[0][0] = 1; m_Transform.x1 = 1;
m_Transform[1][1] = -1; m_Transform.y2 = -1;
m_Transform[1][0] = m_Transform[0][1] = 0; m_Transform.x2 = m_Transform.y1 = 0;
break; break;
case CMP_ROTATE_CLOCKWISE: /* Rotate + */ case CMP_ROTATE_CLOCKWISE: /* Rotate + */
TempMat[0][0] = TempMat[1][1] = 0; temp.x1 = temp.y2 = 0;
TempMat[0][1] = 1; temp.y1 = 1;
TempMat[1][0] = -1; temp.x2 = -1;
Transform = TRUE; Transform = true;
break; break;
case CMP_ROTATE_COUNTERCLOCKWISE: /* Rotate - */ case CMP_ROTATE_COUNTERCLOCKWISE: /* Rotate - */
TempMat[0][0] = TempMat[1][1] = 0; temp.x1 = temp.y2 = 0;
TempMat[0][1] = -1; temp.y1 = -1;
TempMat[1][0] = 1; temp.x2 = 1;
Transform = TRUE; Transform = true;
break; break;
case CMP_MIRROR_Y: /* MirrorY */ case CMP_MIRROR_Y: /* MirrorY */
TempMat[0][0] = -1; temp.x1 = -1;
TempMat[1][1] = 1; temp.y2 = 1;
TempMat[0][1] = TempMat[1][0] = 0; temp.y1 = temp.x2 = 0;
Transform = TRUE; Transform = true;
break; break;
case CMP_MIRROR_X: /* MirrorX */ case CMP_MIRROR_X: /* MirrorX */
TempMat[0][0] = 1; temp.x1 = 1;
TempMat[1][1] = -1; temp.y2 = -1;
TempMat[0][1] = TempMat[1][0] = 0; temp.y1 = temp.x2 = 0;
Transform = TRUE; Transform = TRUE;
break; break;
case CMP_ORIENT_90: case CMP_ORIENT_90:
...@@ -841,24 +838,13 @@ void SCH_COMPONENT::SetOrientation( int aOrientation ) ...@@ -841,24 +838,13 @@ void SCH_COMPONENT::SetOrientation( int aOrientation )
* have: * have:
* transform coord = old_m_Transform * coord * TempMat * transform coord = old_m_Transform * coord * TempMat
*/ */
int NewMatrix[2][2]; TRANSFORM newTransform;
NewMatrix[0][0] = m_Transform[0][0] *TempMat[0][0] +
m_Transform[1][0] *TempMat[0][1];
NewMatrix[0][1] = m_Transform[0][1] *TempMat[0][0] +
m_Transform[1][1] *TempMat[0][1];
NewMatrix[1][0] = m_Transform[0][0] *TempMat[1][0] +
m_Transform[1][0] *TempMat[1][1];
NewMatrix[1][1] = m_Transform[0][1] *TempMat[1][0] + newTransform.x1 = m_Transform.x1 * temp.x1 + m_Transform.x2 * temp.y1;
m_Transform[1][1] *TempMat[1][1]; newTransform.y1 = m_Transform.y1 * temp.x1 + m_Transform.y2 * temp.y1;
newTransform.x2 = m_Transform.x1 * temp.x2 + m_Transform.x2 * temp.y2;
m_Transform[0][0] = NewMatrix[0][0]; newTransform.y2 = m_Transform.y1 * temp.x2 + m_Transform.y2 * temp.y2;
m_Transform[0][1] = NewMatrix[0][1]; m_Transform = newTransform;
m_Transform[1][0] = NewMatrix[1][0];
m_Transform[1][1] = NewMatrix[1][1];
} }
} }
...@@ -879,7 +865,7 @@ void SCH_COMPONENT::SetOrientation( int aOrientation ) ...@@ -879,7 +865,7 @@ void SCH_COMPONENT::SetOrientation( int aOrientation )
int SCH_COMPONENT::GetOrientation() int SCH_COMPONENT::GetOrientation()
{ {
int type_rotate = CMP_ORIENT_0; int type_rotate = CMP_ORIENT_0;
int ComponentMatOrient[2][2]; TRANSFORM transform;
int ii; int ii;
#define ROTATE_VALUES_COUNT 12 #define ROTATE_VALUES_COUNT 12
...@@ -896,20 +882,21 @@ int SCH_COMPONENT::GetOrientation() ...@@ -896,20 +882,21 @@ int SCH_COMPONENT::GetOrientation()
}; };
// Try to find the current transform option: // Try to find the current transform option:
memcpy( ComponentMatOrient, m_Transform, sizeof( ComponentMatOrient ) ); transform = m_Transform;
for( ii = 0; ii < ROTATE_VALUES_COUNT; ii++ ) for( ii = 0; ii < ROTATE_VALUES_COUNT; ii++ )
{ {
type_rotate = rotate_value[ii]; type_rotate = rotate_value[ii];
SetOrientation( type_rotate ); SetOrientation( type_rotate );
if( memcmp( ComponentMatOrient, m_Transform,
sizeof(ComponentMatOrient) ) == 0 ) if( transform == m_Transform )
return type_rotate; return type_rotate;
} }
// Error: orientation not found in list (should not happen) // Error: orientation not found in list (should not happen)
wxMessageBox( wxT( "Component orientation matrix internal error" ) ); wxMessageBox( wxT( "Component orientation matrix internal error" ) );
memcpy( m_Transform, ComponentMatOrient, sizeof( ComponentMatOrient ) ); m_Transform = transform;
return CMP_NORMAL; return CMP_NORMAL;
} }
...@@ -921,11 +908,7 @@ int SCH_COMPONENT::GetOrientation() ...@@ -921,11 +908,7 @@ int SCH_COMPONENT::GetOrientation()
*/ */
wxPoint SCH_COMPONENT::GetScreenCoord( const wxPoint& coord ) wxPoint SCH_COMPONENT::GetScreenCoord( const wxPoint& coord )
{ {
wxPoint screenpos; return m_Transform.TransformCoordinate( coord );
screenpos.x = m_Transform[0][0] *coord.x + m_Transform[0][1] *coord.y;
screenpos.y = m_Transform[1][0] *coord.x + m_Transform[1][1] *coord.y;
return screenpos;
} }
...@@ -1100,8 +1083,7 @@ bool SCH_COMPONENT::Save( FILE* f ) const ...@@ -1100,8 +1083,7 @@ bool SCH_COMPONENT::Save( FILE* f ) const
return false; return false;
if( fprintf( f, "\t%-4d %-4d %-4d %-4d\n", if( fprintf( f, "\t%-4d %-4d %-4d %-4d\n",
m_Transform[0][0], m_Transform[0][1], m_Transform.x1, m_Transform.y1, m_Transform.x2, m_Transform.y2 ) == EOF )
m_Transform[1][0], m_Transform[1][1] ) == EOF )
return false; return false;
if( fprintf( f, "$EndComp\n" ) == EOF ) if( fprintf( f, "$EndComp\n" ) == EOF )
...@@ -1292,7 +1274,7 @@ bool SCH_COMPONENT::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxP ...@@ -1292,7 +1274,7 @@ bool SCH_COMPONENT::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxP
if( aFindLocation ) if( aFindLocation )
{ {
wxPoint pinpos = pin->m_Pos; wxPoint pinpos = pin->m_Pos;
pinpos = TransformCoordinate( m_Transform, pinpos ); pinpos = m_Transform.TransformCoordinate( pinpos );
*aFindLocation = pinpos + m_Pos; *aFindLocation = pinpos + m_Pos;
} }
return true; return true;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "class_sch_screen.h" #include "class_sch_screen.h"
#include "class_sch_cmp_field.h" #include "class_sch_cmp_field.h"
#include "transform.h"
class SCH_SHEET_PATH; class SCH_SHEET_PATH;
...@@ -62,8 +63,8 @@ public: ...@@ -62,8 +63,8 @@ public:
int m_Convert; /* Handle multiple shape (for instance int m_Convert; /* Handle multiple shape (for instance
* De Morgan conversion) */ * De Morgan conversion) */
int m_Transform[2][2]; /* The rotation/mirror transformation TRANSFORM m_Transform; /* The rotation/mirror transformation
* matrix. */ * matrix. */
private: private:
......
...@@ -147,8 +147,7 @@ LIB_PIN* WinEDA_SchematicFrame::LocatePinEnd( SCH_ITEM* DrawList, ...@@ -147,8 +147,7 @@ LIB_PIN* WinEDA_SchematicFrame::LocatePinEnd( SCH_ITEM* DrawList,
// and in schematic Y axis is top to bottom // and in schematic Y axis is top to bottom
else // calculate the pin position in schematic else // calculate the pin position in schematic
pinpos = TransformCoordinate( DrawLibItem->m_Transform, pinpos ) pinpos = DrawLibItem->m_Transform.TransformCoordinate( pinpos ) + DrawLibItem->m_Pos;
+ DrawLibItem->m_Pos;
if( pos == pinpos ) if( pos == pinpos )
return Pin; return Pin;
...@@ -261,8 +260,7 @@ wxPoint ReturnPinPhysicalPosition( LIB_PIN* Pin, SCH_COMPONENT* DrawLibItem ) ...@@ -261,8 +260,7 @@ wxPoint ReturnPinPhysicalPosition( LIB_PIN* Pin, SCH_COMPONENT* DrawLibItem )
NEGATE( PinPos.y ); NEGATE( PinPos.y );
else else
PinPos = TransformCoordinate( DrawLibItem->m_Transform, PinPos = DrawLibItem->m_Transform.TransformCoordinate( Pin->m_Pos ) + DrawLibItem->m_Pos;
Pin->m_Pos ) + DrawLibItem->m_Pos;
return PinPos; return PinPos;
} }
......
...@@ -51,10 +51,10 @@ void WinEDA_SchematicFrame::StartMoveCmpField( SCH_FIELD* aField, wxDC* DC ) ...@@ -51,10 +51,10 @@ void WinEDA_SchematicFrame::StartMoveCmpField( SCH_FIELD* aField, wxDC* DC )
// under some circumstances, but that inversion is not preserved by all // under some circumstances, but that inversion is not preserved by all
// combinations of mirroring and rotation. The following clause is true // combinations of mirroring and rotation. The following clause is true
// when the number of rotations and the number of mirrorings are both odd. // when the number of rotations and the number of mirrorings are both odd.
if( comp->m_Transform[1][0] * comp->m_Transform[0][1] < 0 ) if( comp->m_Transform.x2 * comp->m_Transform.y1 < 0 )
NEGATE( newpos.y ); NEGATE( newpos.y );
newpos = TransformCoordinate( comp->m_Transform, newpos ) + pos; newpos = comp->m_Transform.TransformCoordinate( newpos ) + pos;
DrawPanel->CursorOff( DC ); DrawPanel->CursorOff( DC );
GetScreen()->m_Curseur = newpos; GetScreen()->m_Curseur = newpos;
...@@ -184,7 +184,6 @@ modified!\nYou must create a new power" ) ); ...@@ -184,7 +184,6 @@ modified!\nYou must create a new power" ) );
static void MoveCmpField( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ) static void MoveCmpField( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
{ {
wxPoint pos; wxPoint pos;
int x1, y1;
int fieldNdx; int fieldNdx;
WinEDA_SchematicFrame* frame = (WinEDA_SchematicFrame*) panel->GetParent(); WinEDA_SchematicFrame* frame = (WinEDA_SchematicFrame*) panel->GetParent();
...@@ -205,13 +204,9 @@ static void MoveCmpField( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ) ...@@ -205,13 +204,9 @@ static void MoveCmpField( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
pos = ( (SCH_COMPONENT*) currentField->GetParent() )->m_Pos; pos = ( (SCH_COMPONENT*) currentField->GetParent() )->m_Pos;
/* Positions are calculated by the transpose matrix, Rotating mirror. */ /* Positions are calculated by the transpose matrix, Rotating mirror. */
x1 = panel->GetScreen()->m_Curseur.x - pos.x; wxPoint pt( panel->GetScreen()->m_Curseur - pos );
y1 = panel->GetScreen()->m_Curseur.y - pos.y;
currentField->m_Pos.x = pos.x + component->m_Transform[0][0] * x1 + currentField->m_Pos = pos + component->m_Transform.TransformCoordinate( pt );
component->m_Transform[1][0] * y1;
currentField->m_Pos.y = pos.y + component->m_Transform[0][1] * x1 +
component->m_Transform[1][1] * y1;
currentField->Draw( panel, DC, wxPoint( 0, 0 ), g_XorMode ); currentField->Draw( panel, DC, wxPoint( 0, 0 ), g_XorMode );
} }
......
...@@ -222,26 +222,23 @@ void Dialog_BodyGraphicText_Properties::OnOkClick( wxCommandEvent& event ) ...@@ -222,26 +222,23 @@ void Dialog_BodyGraphicText_Properties::OnOkClick( wxCommandEvent& event )
void WinEDA_LibeditFrame::EditSymbolText(wxDC* DC, LIB_DRAW_ITEM* DrawItem) void WinEDA_LibeditFrame::EditSymbolText( wxDC* DC, LIB_DRAW_ITEM* DrawItem )
{ {
int DrawMode = g_XorMode; int DrawMode = g_XorMode;
if ( ( DrawItem == NULL ) if ( ( DrawItem == NULL ) || ( DrawItem->Type() != COMPONENT_GRAPHIC_TEXT_DRAW_TYPE ) )
|| ( DrawItem->Type() != COMPONENT_GRAPHIC_TEXT_DRAW_TYPE ) )
return; return;
/* Deleting old text. */ /* Deleting old text. */
if( DC) if( DC )
DrawItem->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, DrawMode, NULL, DrawItem->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, DrawMode, NULL, DefaultTransform );
DefaultTransformMatrix );
Dialog_BodyGraphicText_Properties * frame = Dialog_BodyGraphicText_Properties * frame =
new Dialog_BodyGraphicText_Properties( this, new Dialog_BodyGraphicText_Properties( this, (LIB_TEXT*) DrawItem );
(LIB_TEXT*) DrawItem );
frame->ShowModal(); frame->ShowModal();
frame->Destroy(); frame->Destroy();
OnModify( ); OnModify();
/* Display new text. */ /* Display new text. */
if( DC ) if( DC )
...@@ -249,42 +246,6 @@ void WinEDA_LibeditFrame::EditSymbolText(wxDC* DC, LIB_DRAW_ITEM* DrawItem) ...@@ -249,42 +246,6 @@ void WinEDA_LibeditFrame::EditSymbolText(wxDC* DC, LIB_DRAW_ITEM* DrawItem)
if ( ( DrawItem->m_Flags & IS_MOVED ) == 0 ) if ( ( DrawItem->m_Flags & IS_MOVED ) == 0 )
DrawMode = GR_DEFAULT_DRAWMODE; DrawMode = GR_DEFAULT_DRAWMODE;
DrawItem->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, DrawMode, NULL, DrawItem->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, DrawMode, NULL, DefaultTransform );
DefaultTransformMatrix );
} }
} }
/****************************************************/
void WinEDA_LibeditFrame::RotateSymbolText(wxDC * DC)
/****************************************************/
/*
90 deg Graphic text Rotation .
*/
{
LIB_TEXT* DrawItem = (LIB_TEXT *) m_drawItem;
if( DrawItem == NULL )
return;
/* Erase drawing (can be within a move command) */
if ( DrawPanel->ManageCurseur == NULL)
DrawItem->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, g_XorMode, NULL,
DefaultTransformMatrix );
else
DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
if( DrawItem->m_Orient == TEXT_ORIENT_HORIZ )
DrawItem->m_Orient = TEXT_ORIENT_VERT;
else
DrawItem->m_Orient = TEXT_ORIENT_HORIZ;
OnModify( );
/* Redraw item with new orient */
if ( DrawPanel->ManageCurseur == NULL )
DrawItem->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, GR_DEFAULT_DRAWMODE,
NULL, DefaultTransformMatrix );
else
DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
}
/****************************************/
/* Modules to handle component drawing. */
/****************************************/
#include "fctsys.h"
#include "gr_basic.h"
#include "common.h"
#include "class_drawpanel.h"
#include "program.h"
#include "general.h"
#include "protos.h"
#include "class_library.h"
#include <boost/foreach.hpp>
//#define DRAW_ARC_WITH_ANGLE // Used to select function to draw arcs
/***************************************************************************/
/** Function TransformCoordinate
* Calculate the wew coordinate from the old one, according to the transform
* matrix.
* @param aTransformMatrix = rotation, mirror .. matrix
* @param aPosition = the position to transform
* @return the new coordinate
*/
/***************************************************************************/
wxPoint TransformCoordinate( const int aTransformMatrix[2][2],
const wxPoint& aPosition )
{
wxPoint new_pos;
new_pos.x = ( aTransformMatrix[0][0] * aPosition.x ) +
( aTransformMatrix[0][1] * aPosition.y );
new_pos.y = ( aTransformMatrix[1][0] * aPosition.x ) +
( aTransformMatrix[1][1] * aPosition.y );
return new_pos;
}
/*****************************************************************************
* Routine to rotate the given angular direction by the given Transformation. *
* Input (and output) angles must be as follows: *
* Unit is 0.1 degre *
* Angle1 in [0..3600], Angle2 > Angle1 in [0..7200]. Arc is assumed to be *
* less than 180.0 degrees. *
* Algorithm: *
* Map the angles to a point on the unit circle which is mapped using the *
* transform (only mirror and rotate so it remains on the unit circle) to *
* a new point which is used to detect new angle. *
*****************************************************************************/
bool MapAngles( int* Angle1, int* Angle2, const int TransMat[2][2] )
{
int Angle, Delta;
double x, y, t;
bool swap = FALSE;
Delta = *Angle2 - *Angle1;
if( Delta >= 1800 )
{
*Angle1 -= 1;
*Angle2 += 1;
}
x = cos( *Angle1 * M_PI / 1800.0 );
y = sin( *Angle1 * M_PI / 1800.0 );
t = x * TransMat[0][0] + y * TransMat[0][1];
y = x * TransMat[1][0] + y * TransMat[1][1];
x = t;
*Angle1 = (int) ( atan2( y, x ) * 1800.0 / M_PI + 0.5 );
x = cos( *Angle2 * M_PI / 1800.0 );
y = sin( *Angle2 * M_PI / 1800.0 );
t = x * TransMat[0][0] + y * TransMat[0][1];
y = x * TransMat[1][0] + y * TransMat[1][1];
x = t;
*Angle2 = (int) ( atan2( y, x ) * 1800.0 / M_PI + 0.5 );
NORMALIZE_ANGLE( *Angle1 );
NORMALIZE_ANGLE( *Angle2 );
if( *Angle2 < *Angle1 )
*Angle2 += 3600;
if( *Angle2 - *Angle1 > 1800 ) /* Need to swap the two angles. */
{
Angle = (*Angle1);
*Angle1 = (*Angle2);
*Angle2 = Angle;
NORMALIZE_ANGLE( *Angle1 );
NORMALIZE_ANGLE( *Angle2 );
if( *Angle2 < *Angle1 )
*Angle2 += 3600;
swap = TRUE;
}
if( Delta >= 1800 )
{
*Angle1 += 1;
*Angle2 -= 1;
}
return swap;
}
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include "protos.h" #include "protos.h"
#include "hotkeys.h" #include "hotkeys.h"
#include "transform.h"
#include <wx/snglinst.h> #include <wx/snglinst.h>
...@@ -83,7 +85,7 @@ int g_ItemSelectetColor = BROWN; ...@@ -83,7 +85,7 @@ int g_ItemSelectetColor = BROWN;
// in eeschema // in eeschema
int g_InvisibleItemColor = DARKGRAY; int g_InvisibleItemColor = DARKGRAY;
int DefaultTransformMatrix[2][2] = { { 1, 0 }, { 0, -1 } }; TRANSFORM DefaultTransform = TRANSFORM( 1, 0, 0, -1 );
/************************************/ /************************************/
......
...@@ -183,7 +183,7 @@ SCH_ITEM* WinEDA_SchematicFrame::FindComponentAndItem( const wxString& component ...@@ -183,7 +183,7 @@ SCH_ITEM* WinEDA_SchematicFrame::FindComponentAndItem( const wxString& component
} }
wxPoint delta; wxPoint delta;
pos -= Component->m_Pos; pos -= Component->m_Pos;
delta = TransformCoordinate( Component->m_Transform, pos ); delta = Component->m_Transform.TransformCoordinate( pos );
pos = delta + Component->m_Pos; pos = delta + Component->m_Pos;
wxPoint old_cursor_position = sheet->LastScreen()->m_Curseur; wxPoint old_cursor_position = sheet->LastScreen()->m_Curseur;
......
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
static void ShowWhileMoving( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ); static void ShowWhileMoving( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
static void ExitPlaceCmp( WinEDA_DrawPanel* Panel, wxDC* DC ); static void ExitPlaceCmp( WinEDA_DrawPanel* Panel, wxDC* DC );
static int OldTransMat[2][2]; static TRANSFORM OldTransform;
static wxPoint OldPos; static wxPoint OldPos;
wxString WinEDA_SchematicFrame::SelectFromLibBrowser( void ) wxString WinEDA_SchematicFrame::SelectFromLibBrowser( void )
...@@ -294,7 +294,7 @@ static void ExitPlaceCmp( WinEDA_DrawPanel* Panel, wxDC* DC ) ...@@ -294,7 +294,7 @@ static void ExitPlaceCmp( WinEDA_DrawPanel* Panel, wxDC* DC )
{ {
wxPoint move_vector = OldPos - Component->m_Pos; wxPoint move_vector = OldPos - Component->m_Pos;
Component->Move( move_vector ); Component->Move( move_vector );
memcpy( Component->m_Transform, OldTransMat, sizeof(OldTransMat) ); Component->m_Transform = OldTransform;
Component->m_Flags = 0; Component->m_Flags = 0;
} }
...@@ -401,8 +401,7 @@ void WinEDA_SchematicFrame::ConvertPart( SCH_COMPONENT* DrawComponent, ...@@ -401,8 +401,7 @@ void WinEDA_SchematicFrame::ConvertPart( SCH_COMPONENT* DrawComponent,
} }
void WinEDA_SchematicFrame::StartMovePart( SCH_COMPONENT* Component, void WinEDA_SchematicFrame::StartMovePart( SCH_COMPONENT* Component, wxDC* DC )
wxDC* DC )
{ {
if( Component == NULL ) if( Component == NULL )
return; return;
...@@ -426,7 +425,7 @@ void WinEDA_SchematicFrame::StartMovePart( SCH_COMPONENT* Component, ...@@ -426,7 +425,7 @@ void WinEDA_SchematicFrame::StartMovePart( SCH_COMPONENT* Component,
DrawPanel->ForceCloseManageCurseur = ExitPlaceCmp; DrawPanel->ForceCloseManageCurseur = ExitPlaceCmp;
GetScreen()->SetCurItem( Component ); GetScreen()->SetCurItem( Component );
OldPos = Component->m_Pos; OldPos = Component->m_Pos;
memcpy( OldTransMat, Component->m_Transform, sizeof(OldTransMat) ); OldTransform = Component->m_Transform;
#if 1 #if 1
......
...@@ -88,16 +88,13 @@ static Ki_HotkeyInfo HkResetLocalCoord( wxT( "Reset local coord." ), ...@@ -88,16 +88,13 @@ static Ki_HotkeyInfo HkResetLocalCoord( wxT( "Reset local coord." ),
HK_RESET_LOCAL_COORD, ' ' ); HK_RESET_LOCAL_COORD, ' ' );
/* Undo */ /* Undo */
static Ki_HotkeyInfo HkUndo( wxT( "Undo" ), HK_UNDO, GR_KB_CTRL + 'Z', static Ki_HotkeyInfo HkUndo( wxT( "Undo" ), HK_UNDO, GR_KB_CTRL + 'Z', (int) wxID_UNDO );
(int) wxID_UNDO );
/* Redo */ /* Redo */
#if !defined( __WXMAC__ ) #if !defined( __WXMAC__ )
static Ki_HotkeyInfo HkRedo( wxT( "Redo" ), HK_REDO, GR_KB_CTRL + 'Y', static Ki_HotkeyInfo HkRedo( wxT( "Redo" ), HK_REDO, GR_KB_CTRL + 'Y', (int) wxID_REDO );
(int) wxID_REDO );
#else #else
static Ki_HotkeyInfo HkRedo( wxT( "Redo" ), HK_REDO, static Ki_HotkeyInfo HkRedo( wxT( "Redo" ), HK_REDO, GR_KB_SHIFT + GR_KB_CTRL + 'Z',
GR_KB_SHIFT + GR_KB_CTRL + 'Z',
(int) wxID_REDO ); (int) wxID_REDO );
#endif #endif
...@@ -131,27 +128,21 @@ static Ki_HotkeyInfo HkCopyComponentOrText( wxT( "Copy Component or Label" ), ...@@ -131,27 +128,21 @@ static Ki_HotkeyInfo HkCopyComponentOrText( wxT( "Copy Component or Label" ),
HK_COPY_COMPONENT_OR_LABEL, 'C', HK_COPY_COMPONENT_OR_LABEL, 'C',
ID_POPUP_SCH_COPY_ITEM ); ID_POPUP_SCH_COPY_ITEM );
static Ki_HotkeyInfo HkDrag( wxT( "Drag Schematic Item" ), static Ki_HotkeyInfo HkDrag( wxT( "Drag Schematic Item" ), HK_DRAG, 'G',
HK_DRAG, 'G',
ID_POPUP_SCH_DRAG_CMP_REQUEST ); ID_POPUP_SCH_DRAG_CMP_REQUEST );
static Ki_HotkeyInfo HkMove2Drag( wxT( "Switch move block to drag block" ), static Ki_HotkeyInfo HkMove2Drag( wxT( "Switch move block to drag block" ),
HK_MOVEBLOCK_TO_DRAGBLOCK, '\t' ); HK_MOVEBLOCK_TO_DRAGBLOCK, '\t' );
static Ki_HotkeyInfo HkInsert( wxT( "Repeat Last Item" ), HK_REPEAT_LAST, static Ki_HotkeyInfo HkInsert( wxT( "Repeat Last Item" ), HK_REPEAT_LAST, WXK_INSERT );
WXK_INSERT );
static Ki_HotkeyInfo HkDelete( wxT( "Delete Item" ), HK_DELETE, WXK_DELETE ); static Ki_HotkeyInfo HkDelete( wxT( "Delete Item" ), HK_DELETE, WXK_DELETE );
static Ki_HotkeyInfo HkFindItem( wxT( "Find Item" ), HK_FIND_ITEM, 'F' static Ki_HotkeyInfo HkFindItem( wxT( "Find Item" ), HK_FIND_ITEM, 'F' + GR_KB_CTRL );
+ GR_KB_CTRL ); static Ki_HotkeyInfo HkFindNextItem( wxT( "Find Next Item" ), HK_FIND_NEXT_ITEM, WXK_F5 );
static Ki_HotkeyInfo HkFindNextItem( wxT( "Find Next Item" ), HK_FIND_NEXT_ITEM,
WXK_F5 );
static Ki_HotkeyInfo HkFindNextDrcMarker( wxT( "Find next DRC marker" ), HK_FIND_NEXT_DRC_MARKER, static Ki_HotkeyInfo HkFindNextDrcMarker( wxT( "Find next DRC marker" ), HK_FIND_NEXT_DRC_MARKER,
WXK_F5 + GR_KB_SHIFT ); WXK_F5 + GR_KB_SHIFT );
// Special keys for library editor: // Special keys for library editor:
static Ki_HotkeyInfo HkCreatePin( wxT( "Create Pin" ), static Ki_HotkeyInfo HkCreatePin( wxT( "Create Pin" ), HK_LIBEDIT_CREATE_PIN, 'P' );
HK_LIBEDIT_CREATE_PIN, 'P' ); static Ki_HotkeyInfo HkInsertPin( wxT( "Repeat Pin" ), HK_REPEAT_LAST, WXK_INSERT );
static Ki_HotkeyInfo HkInsertPin( wxT( "Repeat Pin" ), HK_REPEAT_LAST,
WXK_INSERT );
static Ki_HotkeyInfo HkMovePin( wxT( "Move Pin" ), HK_LIBEDIT_MOVE_GRAPHIC_ITEM, 'M' ); static Ki_HotkeyInfo HkMovePin( wxT( "Move Pin" ), HK_LIBEDIT_MOVE_GRAPHIC_ITEM, 'M' );
...@@ -256,8 +247,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -256,8 +247,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
cmd.SetEventObject( this ); cmd.SetEventObject( this );
bool ItemInEdit = GetScreen()->GetCurItem() bool ItemInEdit = GetScreen()->GetCurItem()&& GetScreen()->GetCurItem()->m_Flags;
&& GetScreen()->GetCurItem()->m_Flags;
bool RefreshToolBar = FALSE; bool RefreshToolBar = FALSE;
SCH_SCREEN* screen = GetScreen(); SCH_SCREEN* screen = GetScreen();
...@@ -272,8 +262,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -272,8 +262,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
hotkey += 'A' - 'a'; hotkey += 'A' - 'a';
// Search command from key : // Search command from key :
Ki_HotkeyInfo* HK_Descr = GetDescriptorFromHotkey( hotkey, Ki_HotkeyInfo* HK_Descr = GetDescriptorFromHotkey( hotkey, s_Common_Hotkey_List );
s_Common_Hotkey_List );
if( HK_Descr == NULL ) if( HK_Descr == NULL )
HK_Descr = GetDescriptorFromHotkey( hotkey, s_Schematic_Hotkey_List ); HK_Descr = GetDescriptorFromHotkey( hotkey, s_Schematic_Hotkey_List );
if( HK_Descr == NULL ) if( HK_Descr == NULL )
...@@ -322,8 +311,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -322,8 +311,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
case HK_REDO: case HK_REDO:
if( !ItemInEdit ) if( !ItemInEdit )
{ {
wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, HK_Descr->m_IdMenuEvent );
HK_Descr->m_IdMenuEvent );
wxPostEvent( this, event ); wxPostEvent( this, event );
} }
break; break;
...@@ -383,8 +371,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -383,8 +371,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
{ {
// switch to m_ID_current_state = ID_COMPONENT_BUTT; // switch to m_ID_current_state = ID_COMPONENT_BUTT;
if( m_ID_current_state != ID_COMPONENT_BUTT ) if( m_ID_current_state != ID_COMPONENT_BUTT )
SetToolID( ID_COMPONENT_BUTT, wxCURSOR_PENCIL, SetToolID( ID_COMPONENT_BUTT, wxCURSOR_PENCIL, _( "Add Component" ) );
_( "Add Component" ) );
OnLeftClick( DC, MousePos ); OnLeftClick( DC, MousePos );
} }
break; break;
...@@ -428,8 +415,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -428,8 +415,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
if( !ItemInEdit ) if( !ItemInEdit )
{ {
if( m_ID_current_state != ID_NOCONN_BUTT ) if( m_ID_current_state != ID_NOCONN_BUTT )
SetToolID( ID_NOCONN_BUTT, wxCURSOR_PENCIL, SetToolID( ID_NOCONN_BUTT, wxCURSOR_PENCIL, _( "Add \"NoNonnect\" Flags" ) );
_( "Add \"NoNonnect\" Flags" ) );
OnLeftClick( DC, MousePos ); OnLeftClick( DC, MousePos );
} }
break; break;
...@@ -439,7 +425,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -439,7 +425,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
{ {
HandleBlockEndByPopUp(BLOCK_ROTATE, DC ); HandleBlockEndByPopUp(BLOCK_ROTATE, DC );
break; break;
} }
if( DrawStruct == NULL ) if( DrawStruct == NULL )
{ {
// Find the schematic object to rotate under the cursor // Find the schematic object to rotate under the cursor
...@@ -494,11 +480,11 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -494,11 +480,11 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
break; break;
case HK_MIRROR_Y_COMPONENT: // Mirror Y (Component) case HK_MIRROR_Y_COMPONENT: // Mirror Y (Component)
if ( screen->m_BlockLocate.m_State != STATE_NO_BLOCK) if ( screen->m_BlockLocate.m_State != STATE_NO_BLOCK )
{ {
HandleBlockEndByPopUp(BLOCK_MIRROR_Y, DC ); HandleBlockEndByPopUp(BLOCK_MIRROR_Y, DC );
break; break;
} }
if( DrawStruct == NULL ) if( DrawStruct == NULL )
DrawStruct = LocateSmallestComponent( (SCH_SCREEN*) GetScreen() ); DrawStruct = LocateSmallestComponent( (SCH_SCREEN*) GetScreen() );
if( DrawStruct ) if( DrawStruct )
...@@ -513,11 +499,11 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -513,11 +499,11 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
break; break;
case HK_MIRROR_X_COMPONENT: // Mirror X (Component) case HK_MIRROR_X_COMPONENT: // Mirror X (Component)
if ( screen->m_BlockLocate.m_State != STATE_NO_BLOCK) //allows bloc operation on hotkey if ( screen->m_BlockLocate.m_State != STATE_NO_BLOCK ) //allows bloc operation on hotkey
{ {
HandleBlockEndByPopUp(BLOCK_MIRROR_X, DC ); HandleBlockEndByPopUp(BLOCK_MIRROR_X, DC );
break; break;
} }
if( DrawStruct == NULL ) if( DrawStruct == NULL )
DrawStruct = LocateSmallestComponent( GetScreen() ); DrawStruct = LocateSmallestComponent( GetScreen() );
if( DrawStruct ) if( DrawStruct )
...@@ -567,7 +553,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -567,7 +553,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
{ {
// If it's a sheet, then check if a pinsheet is under the cursor // If it's a sheet, then check if a pinsheet is under the cursor
SCH_SHEET_PIN* slabel = LocateSheetLabel( (SCH_SHEET*) DrawStruct, SCH_SHEET_PIN* slabel = LocateSheetLabel( (SCH_SHEET*) DrawStruct,
GetScreen()->m_Curseur ); GetScreen()->m_Curseur );
if( slabel ) if( slabel )
DrawStruct = slabel; DrawStruct = slabel;
} }
...@@ -648,9 +634,8 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -648,9 +634,8 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
break; break;
if( DrawStruct == NULL ) if( DrawStruct == NULL )
{ {
DrawStruct = PickStruct( GetScreen()->m_Curseur, DrawStruct = PickStruct( GetScreen()->m_Curseur, GetScreen(),
GetScreen(), LIBITEM | TEXTITEM | LIBITEM | TEXTITEM | LABELITEM | SHEETITEM );
LABELITEM | SHEETITEM );
if( DrawStruct == NULL ) if( DrawStruct == NULL )
break; break;
if( DrawStruct->Type() == TYPE_SCH_COMPONENT ) if( DrawStruct->Type() == TYPE_SCH_COMPONENT )
...@@ -721,8 +706,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -721,8 +706,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
* under the mouse cursor * under the mouse cursor
* Commands are case insensitive * Commands are case insensitive
*/ */
void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey, void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey, EDA_BaseStruct* DrawStruct )
EDA_BaseStruct* DrawStruct )
{ {
wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED ); wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
wxCommandEvent toolCmd( wxEVT_COMMAND_TOOL_CLICKED ); wxCommandEvent toolCmd( wxEVT_COMMAND_TOOL_CLICKED );
...@@ -730,8 +714,7 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -730,8 +714,7 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey,
cmd.SetEventObject( this ); cmd.SetEventObject( this );
wxPoint MousePos = GetScreen()->m_MousePosition; wxPoint MousePos = GetScreen()->m_MousePosition;
bool ItemInEdit = GetScreen()->GetCurItem() bool ItemInEdit = GetScreen()->GetCurItem()&& GetScreen()->GetCurItem()->m_Flags;
&& GetScreen()->GetCurItem()->m_Flags;
if( hotkey == 0 ) if( hotkey == 0 )
return; return;
...@@ -740,8 +723,7 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -740,8 +723,7 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey,
* with non ascii codes like function keys */ * with non ascii codes like function keys */
if( (hotkey >= 'a') && (hotkey <= 'z') ) if( (hotkey >= 'a') && (hotkey <= 'z') )
hotkey += 'A' - 'a'; hotkey += 'A' - 'a';
Ki_HotkeyInfo* HK_Descr = GetDescriptorFromHotkey( hotkey, Ki_HotkeyInfo* HK_Descr = GetDescriptorFromHotkey( hotkey, s_Common_Hotkey_List );
s_Common_Hotkey_List );
if( HK_Descr == NULL ) if( HK_Descr == NULL )
HK_Descr = GetDescriptorFromHotkey( hotkey, s_LibEdit_Hotkey_List ); HK_Descr = GetDescriptorFromHotkey( hotkey, s_LibEdit_Hotkey_List );
if( HK_Descr == NULL ) if( HK_Descr == NULL )
...@@ -843,7 +825,7 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -843,7 +825,7 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey,
case HK_ROTATE: case HK_ROTATE:
m_drawItem = LocateItemUsingCursor(); m_drawItem = LocateItemUsingCursor();
if( m_drawItem ) if( m_drawItem && !m_drawItem->InEditMode() )
{ {
switch( m_drawItem->Type() ) switch( m_drawItem->Type() )
{ {
...@@ -875,7 +857,7 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -875,7 +857,7 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey,
case HK_DELETE: case HK_DELETE:
m_drawItem = LocateItemUsingCursor(); m_drawItem = LocateItemUsingCursor();
if( m_drawItem ) if( m_drawItem && !m_drawItem->InEditMode() )
{ {
wxCommandEvent evt; wxCommandEvent evt;
evt.SetId( ID_POPUP_LIBEDIT_DELETE_ITEM ); evt.SetId( ID_POPUP_LIBEDIT_DELETE_ITEM );
...@@ -886,7 +868,7 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -886,7 +868,7 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey,
case HK_LIBEDIT_MOVE_GRAPHIC_ITEM: case HK_LIBEDIT_MOVE_GRAPHIC_ITEM:
m_drawItem = LocateItemUsingCursor(); m_drawItem = LocateItemUsingCursor();
if( m_drawItem ) if( m_drawItem && !m_drawItem->InEditMode() )
{ {
wxCommandEvent evt; wxCommandEvent evt;
evt.SetId( ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST ); evt.SetId( ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST );
...@@ -897,7 +879,7 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -897,7 +879,7 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey,
case HK_DRAG: case HK_DRAG:
m_drawItem = LocateItemUsingCursor(); m_drawItem = LocateItemUsingCursor();
if( m_drawItem ) if( m_drawItem && !m_drawItem->InEditMode() )
{ {
wxCommandEvent evt; wxCommandEvent evt;
evt.SetId( ID_POPUP_LIBEDIT_MODIFY_ITEM ); evt.SetId( ID_POPUP_LIBEDIT_MODIFY_ITEM );
......
...@@ -12,17 +12,56 @@ ...@@ -12,17 +12,56 @@
#include "general.h" #include "general.h"
#include "protos.h" #include "protos.h"
#include "lib_arc.h" #include "lib_arc.h"
#include "transform.h"
//! @brief Given three points A B C, compute the circumcenter of the resulting triangle
//! reference: http://en.wikipedia.org/wiki/Circumscribed_circle
//! Coordinates of circumcenter in Cartesian coordinates
static wxPoint calcCenter( const wxPoint& A, const wxPoint& B, const wxPoint& C )
{
double circumCenterX, circumCenterY;
double Ax = (double) A.x;
double Ay = (double) A.y;
double Bx = (double) B.x;
double By = (double) B.y;
double Cx = (double) C.x;
double Cy = (double) C.y;
wxPoint circumCenter;
double D = 2.0 * ( Ax * ( By - Cy ) + Bx * ( Cy - Ay ) + Cx * ( Ay - By ) );
// prevent division / 0
if( fabs( D ) < 1e-7 )
D = 1e-7;
circumCenterX = ( (Ay * Ay + Ax * Ax) * (By - Cy) +
(By * By + Bx * Bx) * (Cy - Ay) +
(Cy * Cy + Cx * Cx) * (Ay - By) ) / D;
circumCenterY = ( (Ay * Ay + Ax * Ax) * (Cx - Bx) +
(By * By + Bx * Bx) * (Ax - Cx) +
(Cy * Cy + Cx * Cx) * (Bx - Ax) ) / D;
circumCenter.x = (int) circumCenterX;
circumCenter.y = (int) circumCenterY;
return circumCenter;
}
LIB_ARC::LIB_ARC( LIB_COMPONENT* aParent ) : LIB_DRAW_ITEM( COMPONENT_ARC_DRAW_TYPE, aParent ) LIB_ARC::LIB_ARC( LIB_COMPONENT* aParent ) : LIB_DRAW_ITEM( COMPONENT_ARC_DRAW_TYPE, aParent )
{ {
m_Radius = 0; m_Radius = 0;
m_t1 = 0; m_t1 = 0;
m_t2 = 0; m_t2 = 0;
m_Width = 0; m_Width = 0;
m_Fill = NO_FILL; m_Fill = NO_FILL;
m_isFillable = true; m_isFillable = true;
m_typeName = _( "Arc" ); m_typeName = _( "Arc" );
m_editState = 0;
m_lastEditState = 0;
} }
...@@ -130,7 +169,7 @@ bool LIB_ARC::HitTest( const wxPoint& aRefPoint ) ...@@ -130,7 +169,7 @@ bool LIB_ARC::HitTest( const wxPoint& aRefPoint )
if( mindist < MINIMUM_SELECTION_DISTANCE ) if( mindist < MINIMUM_SELECTION_DISTANCE )
mindist = MINIMUM_SELECTION_DISTANCE; mindist = MINIMUM_SELECTION_DISTANCE;
return HitTest( aRefPoint, mindist, DefaultTransformMatrix ); return HitTest( aRefPoint, mindist, DefaultTransform );
} }
/** Function HitTest /** Function HitTest
...@@ -140,8 +179,7 @@ bool LIB_ARC::HitTest( const wxPoint& aRefPoint ) ...@@ -140,8 +179,7 @@ bool LIB_ARC::HitTest( const wxPoint& aRefPoint )
* of a line) * of a line)
* @param aTransMat = the transform matrix * @param aTransMat = the transform matrix
*/ */
bool LIB_ARC::HitTest( wxPoint aReferencePoint, int aThreshold, bool LIB_ARC::HitTest( wxPoint aReferencePoint, int aThreshold, const TRANSFORM& aTransform )
const int aTransformationMatrix[2][2] )
{ {
// TODO: use aTransMat to calculmates parameters // TODO: use aTransMat to calculmates parameters
...@@ -149,7 +187,7 @@ bool LIB_ARC::HitTest( wxPoint aReferencePoint, int aThreshold, ...@@ -149,7 +187,7 @@ bool LIB_ARC::HitTest( wxPoint aReferencePoint, int aThreshold,
NEGATE( relativePosition.y ); // reverse Y axis NEGATE( relativePosition.y ); // reverse Y axis
int distance = wxRound( EuclideanNorm( TwoPointVector(m_Pos, relativePosition) ) ); int distance = wxRound( EuclideanNorm( TwoPointVector( m_Pos, relativePosition ) ) );
if( abs( distance - m_Radius ) > aThreshold ) if( abs( distance - m_Radius ) > aThreshold )
return false; return false;
...@@ -160,8 +198,8 @@ bool LIB_ARC::HitTest( wxPoint aReferencePoint, int aThreshold, ...@@ -160,8 +198,8 @@ bool LIB_ARC::HitTest( wxPoint aReferencePoint, int aThreshold,
wxPoint startEndVector = TwoPointVector( m_ArcStart, m_ArcEnd); wxPoint startEndVector = TwoPointVector( m_ArcStart, m_ArcEnd);
wxPoint startRelativePositionVector = TwoPointVector( m_ArcStart, relativePosition ); wxPoint startRelativePositionVector = TwoPointVector( m_ArcStart, relativePosition );
wxPoint centerStartVector = TwoPointVector( m_Pos, m_ArcStart); wxPoint centerStartVector = TwoPointVector( m_Pos, m_ArcStart );
wxPoint centerEndVector = TwoPointVector( m_Pos, m_ArcEnd); wxPoint centerEndVector = TwoPointVector( m_Pos, m_ArcEnd );
wxPoint centerRelativePositionVector = TwoPointVector( m_Pos, relativePosition ); wxPoint centerRelativePositionVector = TwoPointVector( m_Pos, relativePosition );
// Compute the cross product to check if the point is in the sector // Compute the cross product to check if the point is in the sector
...@@ -172,7 +210,7 @@ bool LIB_ARC::HitTest( wxPoint aReferencePoint, int aThreshold, ...@@ -172,7 +210,7 @@ bool LIB_ARC::HitTest( wxPoint aReferencePoint, int aThreshold,
// relative to the start point to end point vector lies // relative to the start point to end point vector lies
if( CrossProduct( startEndVector, startRelativePositionVector ) < 0 ) if( CrossProduct( startEndVector, startRelativePositionVector ) < 0 )
{ {
EXCHG(crossProductStart, crossProductEnd); EXCHG( crossProductStart, crossProductEnd );
} }
// When the cross products have a different sign, the point lies in sector // When the cross products have a different sign, the point lies in sector
...@@ -265,15 +303,15 @@ void LIB_ARC::DoMirrorHorizontal( const wxPoint& aCenter ) ...@@ -265,15 +303,15 @@ void LIB_ARC::DoMirrorHorizontal( const wxPoint& aCenter )
void LIB_ARC::DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, void LIB_ARC::DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
const int aTransform[2][2] ) const TRANSFORM& aTransform )
{ {
wxASSERT( aPlotter != NULL ); wxASSERT( aPlotter != NULL );
int t1 = m_t1; int t1 = m_t1;
int t2 = m_t2; int t2 = m_t2;
wxPoint pos = TransformCoordinate( aTransform, m_Pos ) + aOffset; wxPoint pos = aTransform.TransformCoordinate( m_Pos ) + aOffset;
MapAngles( &t1, &t2, aTransform ); aTransform.MapAngles( &t1, &t2 );
if( aFill && m_Fill == FILLED_WITH_BG_BODYCOLOR ) if( aFill && m_Fill == FILLED_WITH_BG_BODYCOLOR )
{ {
...@@ -295,12 +333,35 @@ int LIB_ARC::GetPenSize() ...@@ -295,12 +333,35 @@ int LIB_ARC::GetPenSize()
} }
void LIB_ARC::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, void LIB_ARC::drawEditGraphics( EDA_Rect* aClipBox, wxDC* aDC, int aColor )
const wxPoint& aOffset, int aColor, int aDrawMode,
void* aData, const int aTransformMatrix[2][2] )
{ {
wxPoint pos1, pos2, posc; // Thie edit indicators only get drawn when a new arc is being drawn.
if( ( m_Flags & IS_NEW ) == 0 )
return;
// Use the last edit state so when the drawing switches from the end mode to the center
// point mode, the last line between the center points gets erased.
if( m_lastEditState == 1 )
{
GRLine( aClipBox, aDC, m_ArcStart.x, -m_ArcStart.y, m_ArcEnd.x, -m_ArcEnd.y, 0, aColor );
}
else
{
GRDashedLine( aClipBox, aDC, m_ArcStart.x, -m_ArcStart.y, m_Pos.x, -m_Pos.y, 0, aColor );
GRDashedLine( aClipBox, aDC, m_ArcEnd.x, -m_ArcEnd.y, m_Pos.x, -m_Pos.y, 0, aColor );
}
}
void LIB_ARC::drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOffset,
int aColor, int aDrawMode, void* aData, const TRANSFORM& aTransform )
{
// DOn't draw the arc until the end point is selected. Only the edit indicators
// get drawn at this time.
if( ( m_Flags & IS_NEW ) && m_lastEditState == 1 )
return;
wxPoint pos1, pos2, posc;
int color = ReturnLayerColor( LAYER_DEVICE ); int color = ReturnLayerColor( LAYER_DEVICE );
if( aColor < 0 ) // Used normal color or selected color if( aColor < 0 ) // Used normal color or selected color
...@@ -309,14 +370,16 @@ void LIB_ARC::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, ...@@ -309,14 +370,16 @@ void LIB_ARC::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
color = g_ItemSelectetColor; color = g_ItemSelectetColor;
} }
else else
{
color = aColor; color = aColor;
}
pos1 = TransformCoordinate( aTransformMatrix, m_ArcEnd ) + aOffset; pos1 = aTransform.TransformCoordinate( m_ArcEnd ) + aOffset;
pos2 = TransformCoordinate( aTransformMatrix, m_ArcStart ) + aOffset; pos2 = aTransform.TransformCoordinate( m_ArcStart ) + aOffset;
posc = TransformCoordinate( aTransformMatrix, m_Pos ) + aOffset; posc = aTransform.TransformCoordinate( m_Pos ) + aOffset;
int pt1 = m_t1; int pt1 = m_t1;
int pt2 = m_t2; int pt2 = m_t2;
bool swap = MapAngles( &pt1, &pt2, aTransformMatrix ); bool swap = aTransform.MapAngles( &pt1, &pt2 );
if( swap ) if( swap )
{ {
EXCHG( pos1.x, pos2.x ); EXCHG( pos1.x, pos2.x );
...@@ -335,18 +398,17 @@ void LIB_ARC::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, ...@@ -335,18 +398,17 @@ void LIB_ARC::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
(m_Flags & IS_MOVED) ? color : ReturnLayerColor( LAYER_DEVICE_BACKGROUND ), (m_Flags & IS_MOVED) ? color : ReturnLayerColor( LAYER_DEVICE_BACKGROUND ),
ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) ); ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) );
else if( fill == FILLED_SHAPE && !aData ) else if( fill == FILLED_SHAPE && !aData )
GRFilledArc( &aPanel->m_ClipBox, aDC, posc.x, posc.y, pt1, pt2, GRFilledArc( &aPanel->m_ClipBox, aDC, posc.x, posc.y, pt1, pt2, m_Radius, color, color );
m_Radius, color, color );
else else
{ {
#ifdef DRAW_ARC_WITH_ANGLE #ifdef DRAW_ARC_WITH_ANGLE
GRArc( &aPanel->m_ClipBox, aDC, posc.x, posc.y, pt1, pt2, GRArc( &aPanel->m_ClipBox, aDC, posc.x, posc.y, pt1, pt2, m_Radius, GetPenSize(), color );
m_Radius, GetPenSize( ), color );
#else #else
GRArc1( &aPanel->m_ClipBox, aDC, pos1.x, pos1.y, pos2.x, pos2.y, GRArc1( &aPanel->m_ClipBox, aDC, pos1.x, pos1.y, pos2.x, pos2.y,
posc.x, posc.y, GetPenSize( ), color ); posc.x, posc.y, GetPenSize(), color );
#endif #endif
} }
...@@ -360,6 +422,26 @@ void LIB_ARC::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, ...@@ -360,6 +422,26 @@ void LIB_ARC::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
} }
void LIB_ARC::saveAttributes()
{
m_savedPos = m_Pos;
m_savedStartPos = m_ArcStart;
m_savedEndPos = m_ArcEnd;
m_savedAngle1 = m_t1;
m_savedAngle2 = m_t2;
}
void LIB_ARC::restoreAttributes()
{
m_Pos = m_savedPos;
m_ArcStart = m_savedStartPos;
m_ArcEnd = m_savedEndPos;
m_t1 = m_savedAngle1;
m_t2 = m_savedAngle2;
}
EDA_Rect LIB_ARC::GetBoundingBox() EDA_Rect LIB_ARC::GetBoundingBox()
{ {
int minX, minY, maxX, maxY, angleStart, angleEnd; int minX, minY, maxX, maxY, angleStart, angleEnd;
...@@ -377,13 +459,13 @@ start(%d, %d), end(%d, %d), radius %d" ), ...@@ -377,13 +459,13 @@ start(%d, %d), end(%d, %d), radius %d" ),
return rect; return rect;
} }
endPos = TransformCoordinate( DefaultTransformMatrix, m_ArcEnd ); endPos = DefaultTransform.TransformCoordinate( m_ArcEnd );
startPos = TransformCoordinate( DefaultTransformMatrix, m_ArcStart ); startPos = DefaultTransform.TransformCoordinate( m_ArcStart );
centerPos = TransformCoordinate( DefaultTransformMatrix, m_Pos ); centerPos = DefaultTransform.TransformCoordinate( m_Pos );
angleStart = m_t1; angleStart = m_t1;
angleEnd = m_t2; angleEnd = m_t2;
if( MapAngles( &angleStart, &angleEnd, DefaultTransformMatrix ) ) if( DefaultTransform.MapAngles( &angleStart, &angleEnd ) )
{ {
EXCHG( endPos.x, startPos.x ); EXCHG( endPos.x, startPos.x );
EXCHG( endPos.y, startPos.y ); EXCHG( endPos.y, startPos.y );
...@@ -436,3 +518,259 @@ void LIB_ARC::DisplayInfo( WinEDA_DrawFrame* aFrame ) ...@@ -436,3 +518,259 @@ void LIB_ARC::DisplayInfo( WinEDA_DrawFrame* aFrame )
aFrame->AppendMsgPanel( _( "Bounding box" ), msg, BROWN ); aFrame->AppendMsgPanel( _( "Bounding box" ), msg, BROWN );
} }
void LIB_ARC::BeginEdit( int aEditMode, const wxPoint aPosition )
{
wxCHECK_RET( ( aEditMode & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0,
wxT( "Invalid edit mode for LIB_ARC object." ) );
if( aEditMode == IS_NEW )
{
m_ArcStart = m_ArcEnd = aPosition;
m_editState = m_lastEditState = 1;
}
else if( aEditMode == IS_MOVED )
{
m_initialPos = m_Pos;
m_initialCursorPos = aPosition;
saveAttributes();
SetEraseLastDrawItem();
}
else
{
// Save the current arc positions in case the resize ia aborted.
saveAttributes();
// The arc center point has to be rotated with while adjusting the
// start or end point, determine the side of this point and the distance
// from the start / end point
wxPoint middlePoint = wxPoint( (m_ArcStart.x + m_ArcEnd.x) / 2,
(m_ArcStart.y + m_ArcEnd.y) / 2 );
wxPoint centerVector = m_Pos - middlePoint;
wxPoint startEndVector = TwoPointVector( m_ArcStart, m_ArcEnd );
m_editCenterDistance = EuclideanNorm( centerVector );
// Determine on which side is the center point
m_editDirection = CrossProduct( startEndVector, centerVector ) ? 1 : -1;
// Drag either the start, end point or the outline
if( HitTestPoints( m_ArcStart, aPosition, MINIMUM_SELECTION_DISTANCE ) )
{
m_editSelectPoint = START;
}
else if( HitTestPoints( m_ArcEnd, aPosition, MINIMUM_SELECTION_DISTANCE ) )
{
m_editSelectPoint = END;
}
else
m_editSelectPoint = OUTLINE;
m_editState = 0;
SetEraseLastDrawItem();
}
m_Flags = aEditMode;
}
bool LIB_ARC::ContinueEdit( const wxPoint aPosition )
{
wxCHECK_MSG( ( m_Flags & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0, false,
wxT( "Bad call to ContinueEdit(). LIB_ARC is not being edited." ) );
if( m_Flags == IS_NEW )
{
if( m_editState == 1 ) // Second position yields the arc segment length.
{
m_ArcEnd = aPosition;
m_editState = 2;
SetEraseLastDrawItem( false );
return true; // Need third position to calculate center point.
}
}
return false;
}
void LIB_ARC::EndEdit( const wxPoint& aPosition, bool aAbort )
{
wxCHECK_RET( ( m_Flags & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0,
wxT( "Bad call to EndEdit(). LIB_ARC is not being edited." ) );
if( aAbort && !IsNew() )
restoreAttributes();
SetEraseLastDrawItem( false );
m_lastEditState = 0;
m_editState = 0;
m_Flags = 0;
}
void LIB_ARC::calcEdit( const wxPoint& aPosition )
{
if( m_Flags == IS_RESIZED )
{
wxPoint newCenterPoint, startPos, endPos;
// Choose the point of the arc to be adjusted
if( m_editSelectPoint == START )
{
startPos = aPosition;
endPos = m_ArcEnd;
}
else if( m_editSelectPoint == END )
{
endPos = aPosition;
startPos = m_ArcStart;
}
else
{
// Use the cursor for adjusting the arc curvature
startPos = m_ArcStart;
endPos = m_ArcEnd;
wxPoint middlePoint = wxPoint( (startPos.x + endPos.x) / 2,
(startPos.y + endPos.y) / 2 );
// If the distance is too small, use the old center point
// else the new center point is calculated over the three points start/end/cursor
if( DistanceLinePoint( startPos, endPos, aPosition ) > MINIMUM_SELECTION_DISTANCE )
{
newCenterPoint = calcCenter( startPos, aPosition, endPos );
}
else
{
newCenterPoint = m_Pos;
}
// Determine if the arc angle is larger than 180 degrees -> this happens if both
// points (cursor position, center point) lie on the same side of the vector
// start-end
int crossA = CrossProduct( TwoPointVector( startPos, endPos ),
TwoPointVector( endPos, aPosition ) );
int crossB = CrossProduct( TwoPointVector( startPos, endPos ),
TwoPointVector( endPos, newCenterPoint ) );
if( ( crossA < 0 && crossB < 0 ) || ( crossA >= 0 && crossB >= 0 ) )
newCenterPoint = m_Pos;
}
if( m_editSelectPoint == START || m_editSelectPoint == END )
{
// Compute the new center point when the start/end points are modified
wxPoint middlePoint = wxPoint( (startPos.x + endPos.x) / 2,
(startPos.y + endPos.y) / 2 );
wxPoint startEndVector = TwoPointVector( startPos, endPos );
wxPoint perpendicularVector = wxPoint( -startEndVector.y, startEndVector.x );
double lengthPerpendicularVector = EuclideanNorm( perpendicularVector );
// prevent too large values, division / 0
if( lengthPerpendicularVector < 1e-1 )
lengthPerpendicularVector = 1e-1;
perpendicularVector.x = (int) ( (double) perpendicularVector.x *
m_editCenterDistance /
lengthPerpendicularVector ) * m_editDirection;
perpendicularVector.y = (int) ( (double) perpendicularVector.y *
m_editCenterDistance /
lengthPerpendicularVector ) * m_editDirection;
newCenterPoint = middlePoint + perpendicularVector;
m_ArcStart = startPos;
m_ArcEnd = endPos;
}
m_Pos = newCenterPoint;
calcRadiusAngles();
}
else if( m_Flags == IS_NEW )
{
if( m_editState == 1 )
{
m_ArcEnd = aPosition;
}
if( m_editState != m_lastEditState )
m_lastEditState = m_editState;
// Keep the arc center point up to date. Otherwise, there will be edit graphic
// artifacts left behind from the initial draw.
int dx, dy;
int cX, cY;
int angle;
cX = aPosition.x;
cY = aPosition.y;
dx = m_ArcEnd.x - m_ArcStart.x;
dy = m_ArcEnd.y - m_ArcStart.y;
cX -= m_ArcStart.x;
cY -= m_ArcStart.y;
angle = (int) ( atan2( (double) dy, (double) dx ) * 1800 / M_PI );
RotatePoint( &dx, &dy, angle ); /* The segment dx, dy is horizontal
* -> Length = dx, dy = 0 */
RotatePoint( &cX, &cY, angle );
cX = dx / 2; /* cX, cY is on the median segment 0.0 a dx, 0 */
RotatePoint( &cX, &cY, -angle );
cX += m_ArcStart.x;
cY += m_ArcStart.y;
m_Pos.x = cX;
m_Pos.y = cY;
calcRadiusAngles();
SetEraseLastDrawItem();
}
else if( m_Flags == IS_MOVED )
{
Move( m_initialPos + aPosition - m_initialCursorPos );
}
}
void LIB_ARC::calcRadiusAngles()
{
wxPoint centerStartVector = TwoPointVector( m_Pos, m_ArcStart );
wxPoint centerEndVector = TwoPointVector( m_Pos, m_ArcEnd );
m_Radius = wxRound( EuclideanNorm( centerStartVector ) );
m_t1 = (int) ( atan2( (double) centerStartVector.y,
(double) centerStartVector.x ) * 1800 / M_PI );
m_t2 = (int) ( atan2( (double) centerEndVector.y,
(double) centerEndVector.x ) * 1800 / M_PI );
NORMALIZE_ANGLE( m_t1 );
NORMALIZE_ANGLE( m_t2 ); // angles = 0 .. 3600
// Restrict angle to less than 180 to avoid PBS display mirror Trace because it is
// assumed that the arc is less than 180 deg to find orientation after rotate or mirror.
if( (m_t2 - m_t1) > 1800 )
m_t2 -= 3600;
else if( (m_t2 - m_t1) <= -1800 )
m_t2 += 3600;
while( (m_t2 - m_t1) >= 1800 )
{
m_t2--;
m_t1++;
}
while( (m_t1 - m_t2) >= 1800 )
{
m_t2++;
m_t1--;
}
NORMALIZE_ANGLE( m_t1 );
if( !IsMoving() )
NORMALIZE_ANGLE( m_t2 );
}
...@@ -9,8 +9,63 @@ ...@@ -9,8 +9,63 @@
#include "lib_draw_item.h" #include "lib_draw_item.h"
class TRANSFORM;
class LIB_ARC : public LIB_DRAW_ITEM class LIB_ARC : public LIB_DRAW_ITEM
{ {
enum SELECT_T
{
START,
END,
OUTLINE,
};
wxPoint m_savedStartPos;
wxPoint m_savedEndPos;
int m_savedAngle1;
int m_savedAngle2;
double m_editCenterDistance;
SELECT_T m_editSelectPoint;
int m_editState;
int m_editDirection;
int m_lastEditState;
/**
* Draws the arc.
*/
void drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOffset,
int aColor, int aDrawMode, void* aData, const TRANSFORM& aTransform );
/**
* Draw the graphics when the arc is being edited.
*/
void drawEditGraphics( EDA_Rect* aClipBox, wxDC* aDC, int aColor );
/**
* See LIB_DRAW_ITEM::saveAttributes().
*/
void saveAttributes();
/**
* See LIB_DRAW_ITEM::restoreAttributes().
*/
void restoreAttributes();
/**
* Calculates the center, radius, and angles at \a aPosition when the arc is being edited.
*
* Note: The center may not necessarily be on the grid.
*
* @param aPosition - The current mouse position in drawing coordinates.
*/
void calcEdit( const wxPoint& aPosition );
/**
* Calculate the radius and angle of an arc using the start, end, and center points.
*/
void calcRadiusAngles();
public: public:
int m_Radius; int m_Radius;
int m_t1; /* First radius angle of the arc in 0.1 degrees. */ int m_t1; /* First radius angle of the arc in 0.1 degrees. */
...@@ -21,7 +76,7 @@ public: ...@@ -21,7 +76,7 @@ public:
int m_Width; /* Line width */ int m_Width; /* Line width */
public: public:
LIB_ARC(LIB_COMPONENT * aParent); LIB_ARC( LIB_COMPONENT * aParent );
LIB_ARC( const LIB_ARC& aArc ); LIB_ARC( const LIB_ARC& aArc );
~LIB_ARC() { } ~LIB_ARC() { }
virtual wxString GetClass() const virtual wxString GetClass() const
...@@ -51,14 +106,10 @@ public: ...@@ -51,14 +106,10 @@ public:
* @param aPosRef - a wxPoint to test * @param aPosRef - a wxPoint to test
* @param aThreshold - max distance to this object (usually the half * @param aThreshold - max distance to this object (usually the half
* thickness of a line) * thickness of a line)
* @param aTransMat - the transform matrix * @param aTransform - the transform matrix
* @return - True if the point aPosRef is near this object * @return - True if the point aPosRef is near this object
*/ */
virtual bool HitTest( wxPoint aPosRef, int aThreshold, const int aTransMat[2][2] ); virtual bool HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform );
void Draw( WinEDA_DrawPanel * aPanel, wxDC * aDC, const wxPoint &aOffset,
int aColor, int aDrawMode, void* aData,
const int aTransformMatrix[2][2] );
virtual EDA_Rect GetBoundingBox(); virtual EDA_Rect GetBoundingBox();
virtual void DisplayInfo( WinEDA_DrawFrame* frame ); virtual void DisplayInfo( WinEDA_DrawFrame* frame );
...@@ -68,6 +119,21 @@ public: ...@@ -68,6 +119,21 @@ public:
*/ */
virtual int GetPenSize( ); virtual int GetPenSize( );
/**
* See LIB_DRAW_ITEM::BeginEdit().
*/
void BeginEdit( int aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) );
/**
* See LIB_DRAW_ITEM::ContinueEdit().
*/
bool ContinueEdit( const wxPoint aNextPoint );
/**
* See LIB_DRAW_ITEM::AbortEdit().
*/
void EndEdit( const wxPoint& aPosition, bool aAbort = false );
protected: protected:
virtual LIB_DRAW_ITEM* DoGenCopy(); virtual LIB_DRAW_ITEM* DoGenCopy();
...@@ -87,7 +153,7 @@ protected: ...@@ -87,7 +153,7 @@ protected:
virtual wxPoint DoGetPosition() { return m_Pos; } virtual wxPoint DoGetPosition() { return m_Pos; }
virtual void DoMirrorHorizontal( const wxPoint& aCenter ); virtual void DoMirrorHorizontal( const wxPoint& aCenter );
virtual void DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, virtual void DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
const int aTransform[2][2] ); const TRANSFORM& aTransform );
virtual int DoGetWidth() { return m_Width; } virtual int DoGetWidth() { return m_Width; }
virtual void DoSetWidth( int aWidth ) { m_Width = aWidth; } virtual void DoSetWidth( int aWidth ) { m_Width = aWidth; }
}; };
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "general.h" #include "general.h"
#include "protos.h" #include "protos.h"
#include "lib_bezier.h" #include "lib_bezier.h"
#include "transform.h"
LIB_BEZIER::LIB_BEZIER( LIB_COMPONENT* aParent ) : LIB_BEZIER::LIB_BEZIER( LIB_COMPONENT* aParent ) :
...@@ -197,7 +198,7 @@ void LIB_BEZIER::DoMirrorHorizontal( const wxPoint& aCenter ) ...@@ -197,7 +198,7 @@ void LIB_BEZIER::DoMirrorHorizontal( const wxPoint& aCenter )
void LIB_BEZIER::DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, void LIB_BEZIER::DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
const int aTransform[2][2] ) const TRANSFORM& aTransform )
{ {
wxASSERT( aPlotter != NULL ); wxASSERT( aPlotter != NULL );
...@@ -211,7 +212,7 @@ void LIB_BEZIER::DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, ...@@ -211,7 +212,7 @@ void LIB_BEZIER::DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
for( i = 0; i < m_PolyPoints.size(); i++ ) for( i = 0; i < m_PolyPoints.size(); i++ )
{ {
wxPoint pos = m_PolyPoints[i]; wxPoint pos = m_PolyPoints[i];
pos = TransformCoordinate( aTransform, pos ) + aOffset; pos = aTransform.TransformCoordinate( pos ) + aOffset;
Poly[i * 2] = pos.x; Poly[i * 2] = pos.x;
Poly[i * 2 + 1] = pos.y; Poly[i * 2 + 1] = pos.y;
} }
...@@ -236,9 +237,8 @@ int LIB_BEZIER::GetPenSize() ...@@ -236,9 +237,8 @@ int LIB_BEZIER::GetPenSize()
return ( m_Width == 0 ) ? g_DrawDefaultLineThickness : m_Width; return ( m_Width == 0 ) ? g_DrawDefaultLineThickness : m_Width;
} }
void LIB_BEZIER::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, void LIB_BEZIER::drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOffset,
const wxPoint& aOffset, int aColor, int aDrawMode, int aColor, int aDrawMode, void* aData, const TRANSFORM& aTransform )
void* aData, const int aTransformMatrix[2][2] )
{ {
wxPoint pos1; wxPoint pos1;
std::vector<wxPoint> PolyPointsTraslated; std::vector<wxPoint> PolyPointsTraslated;
...@@ -253,8 +253,8 @@ void LIB_BEZIER::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, ...@@ -253,8 +253,8 @@ void LIB_BEZIER::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
PolyPointsTraslated.clear(); PolyPointsTraslated.clear();
for( unsigned int i = 0; i < m_PolyPoints.size() ; i++ ) for( unsigned int i = 0; i < m_PolyPoints.size() ; i++ )
PolyPointsTraslated.push_back( TransformCoordinate( aTransformMatrix, PolyPointsTraslated.push_back( aTransform.TransformCoordinate( m_PolyPoints[i] ) +
m_PolyPoints[i] ) + aOffset ); aOffset );
if( aColor < 0 ) // Used normal color or selected color if( aColor < 0 ) // Used normal color or selected color
{ {
...@@ -305,7 +305,7 @@ bool LIB_BEZIER::HitTest( const wxPoint& aRefPos ) ...@@ -305,7 +305,7 @@ bool LIB_BEZIER::HitTest( const wxPoint& aRefPos )
// Have a minimal tolerance for hit test // Have a minimal tolerance for hit test
if ( mindist < MINIMUM_SELECTION_DISTANCE ) if ( mindist < MINIMUM_SELECTION_DISTANCE )
mindist = MINIMUM_SELECTION_DISTANCE; mindist = MINIMUM_SELECTION_DISTANCE;
return HitTest( aRefPos, mindist, DefaultTransformMatrix ); return HitTest( aRefPos, mindist, DefaultTransform );
} }
/** Function HitTest /** Function HitTest
...@@ -314,14 +314,14 @@ bool LIB_BEZIER::HitTest( const wxPoint& aRefPos ) ...@@ -314,14 +314,14 @@ bool LIB_BEZIER::HitTest( const wxPoint& aRefPos )
* @param aThreshold = max distance to a segment * @param aThreshold = max distance to a segment
* @param aTransMat = the transform matrix * @param aTransMat = the transform matrix
*/ */
bool LIB_BEZIER::HitTest( wxPoint aPosRef, int aThreshold, const int aTransMat[2][2] ) bool LIB_BEZIER::HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform )
{ {
wxPoint ref, start, end; wxPoint ref, start, end;
for( unsigned ii = 1; ii < GetCornerCount(); ii++ ) for( unsigned ii = 1; ii < GetCornerCount(); ii++ )
{ {
start = TransformCoordinate( aTransMat, m_PolyPoints[ii - 1] ); start = aTransform.TransformCoordinate( m_PolyPoints[ii - 1] );
end = TransformCoordinate( aTransMat, m_PolyPoints[ii] ); end = aTransform.TransformCoordinate( m_PolyPoints[ii] );
if ( TestSegmentHit( aPosRef, start, end, aThreshold ) ) if ( TestSegmentHit( aPosRef, start, end, aThreshold ) )
return true; return true;
......
...@@ -11,6 +11,12 @@ ...@@ -11,6 +11,12 @@
/**************************************************/ /**************************************************/
class LIB_BEZIER : public LIB_DRAW_ITEM class LIB_BEZIER : public LIB_DRAW_ITEM
{ {
/**
* Draw the bezier curve.
*/
void drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOffset,
int aColor, int aDrawMode, void* aData, const TRANSFORM& aTransform );
public: public:
int m_Width; /* Line width */ int m_Width; /* Line width */
std::vector<wxPoint> m_BezierPoints; // list of parameter (3|4) std::vector<wxPoint> m_BezierPoints; // list of parameter (3|4)
...@@ -54,10 +60,10 @@ public: ...@@ -54,10 +60,10 @@ public:
/** /**
* @param aPosRef = a wxPoint to test * @param aPosRef = a wxPoint to test
* @param aThreshold = max distance to a segment * @param aThreshold = max distance to a segment
* @param aTransMat = the transform matrix * @param aTransform = the transform matrix
* @return true if the point aPosRef is near a segment * @return true if the point aPosRef is near a segment
*/ */
virtual bool HitTest( wxPoint aPosRef, int aThreshold, const int aTransMat[2][2] ); virtual bool HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform );
/** /**
* @return the boundary box for this, in library coordinates * @return the boundary box for this, in library coordinates
...@@ -69,10 +75,6 @@ public: ...@@ -69,10 +75,6 @@ public:
*/ */
virtual int GetPenSize( ); virtual int GetPenSize( );
void Draw( WinEDA_DrawPanel * aPanel, wxDC * aDC, const wxPoint &aOffset,
int aColor, int aDrawMode, void* aData,
const int aTransformMatrix[2][2] );
virtual void DisplayInfo( WinEDA_DrawFrame* aFrame ); virtual void DisplayInfo( WinEDA_DrawFrame* aFrame );
protected: protected:
...@@ -93,7 +95,7 @@ protected: ...@@ -93,7 +95,7 @@ protected:
virtual wxPoint DoGetPosition() { return m_PolyPoints[0]; } virtual wxPoint DoGetPosition() { return m_PolyPoints[0]; }
virtual void DoMirrorHorizontal( const wxPoint& aCenter ); virtual void DoMirrorHorizontal( const wxPoint& aCenter );
virtual void DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, virtual void DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
const int aTransform[2][2] ); const TRANSFORM& aTransform );
virtual int DoGetWidth() { return m_Width; } virtual int DoGetWidth() { return m_Width; }
virtual void DoSetWidth( int aWidth ) { m_Width = aWidth; } virtual void DoSetWidth( int aWidth ) { m_Width = aWidth; }
}; };
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "general.h" #include "general.h"
#include "protos.h" #include "protos.h"
#include "lib_circle.h" #include "lib_circle.h"
#include "transform.h"
LIB_CIRCLE::LIB_CIRCLE( LIB_COMPONENT* aParent ) : LIB_CIRCLE::LIB_CIRCLE( LIB_COMPONENT* aParent ) :
...@@ -79,7 +80,7 @@ bool LIB_CIRCLE::HitTest( const wxPoint& aPosRef ) ...@@ -79,7 +80,7 @@ bool LIB_CIRCLE::HitTest( const wxPoint& aPosRef )
if( mindist < MINIMUM_SELECTION_DISTANCE ) if( mindist < MINIMUM_SELECTION_DISTANCE )
mindist = MINIMUM_SELECTION_DISTANCE; mindist = MINIMUM_SELECTION_DISTANCE;
return HitTest( aPosRef, mindist, DefaultTransformMatrix ); return HitTest( aPosRef, mindist, DefaultTransform );
} }
...@@ -90,9 +91,9 @@ bool LIB_CIRCLE::HitTest( const wxPoint& aPosRef ) ...@@ -90,9 +91,9 @@ bool LIB_CIRCLE::HitTest( const wxPoint& aPosRef )
* thickness of a line) * thickness of a line)
* @param aTransMat = the transform matrix * @param aTransMat = the transform matrix
*/ */
bool LIB_CIRCLE::HitTest( wxPoint aPosRef, int aThreshold, const int aTransMat[2][2] ) bool LIB_CIRCLE::HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform )
{ {
wxPoint relpos = aPosRef - TransformCoordinate( aTransMat, m_Pos ); wxPoint relpos = aPosRef - aTransform.TransformCoordinate( m_Pos );
int dist = wxRound( sqrt( ( (double) relpos.x * relpos.x ) + int dist = wxRound( sqrt( ( (double) relpos.x * relpos.x ) +
( (double) relpos.y * relpos.y ) ) ); ( (double) relpos.y * relpos.y ) ) );
...@@ -169,9 +170,9 @@ void LIB_CIRCLE::DoMirrorHorizontal( const wxPoint& aCenter ) ...@@ -169,9 +170,9 @@ void LIB_CIRCLE::DoMirrorHorizontal( const wxPoint& aCenter )
void LIB_CIRCLE::DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, void LIB_CIRCLE::DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
const int aTransform[2][2] ) const TRANSFORM& aTransform )
{ {
wxPoint pos = TransformCoordinate( aTransform, m_Pos ) + aOffset; wxPoint pos = aTransform.TransformCoordinate( m_Pos ) + aOffset;
if( aFill && m_Fill == FILLED_WITH_BG_BODYCOLOR ) if( aFill && m_Fill == FILLED_WITH_BG_BODYCOLOR )
{ {
...@@ -193,9 +194,8 @@ int LIB_CIRCLE::GetPenSize() ...@@ -193,9 +194,8 @@ int LIB_CIRCLE::GetPenSize()
} }
void LIB_CIRCLE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, void LIB_CIRCLE::drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOffset,
const wxPoint& aOffset, int aColor, int aDrawMode, int aColor, int aDrawMode, void* aData, const TRANSFORM& aTransform )
void* aData, const int aTransformMatrix[2][2] )
{ {
wxPoint pos1; wxPoint pos1;
...@@ -209,7 +209,7 @@ void LIB_CIRCLE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, ...@@ -209,7 +209,7 @@ void LIB_CIRCLE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
else else
color = aColor; color = aColor;
pos1 = TransformCoordinate( aTransformMatrix, m_Pos ) + aOffset; pos1 = aTransform.TransformCoordinate( m_Pos ) + aOffset;
GRSetDrawMode( aDC, aDrawMode ); GRSetDrawMode( aDC, aDrawMode );
FILL_T fill = aData ? NO_FILL : m_Fill; FILL_T fill = aData ? NO_FILL : m_Fill;
...@@ -217,8 +217,7 @@ void LIB_CIRCLE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, ...@@ -217,8 +217,7 @@ void LIB_CIRCLE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
fill = NO_FILL; fill = NO_FILL;
if( fill == FILLED_WITH_BG_BODYCOLOR ) if( fill == FILLED_WITH_BG_BODYCOLOR )
GRFilledCircle( &aPanel->m_ClipBox, aDC, pos1.x, pos1.y, GRFilledCircle( &aPanel->m_ClipBox, aDC, pos1.x, pos1.y, m_Radius, GetPenSize(),
m_Radius, GetPenSize( ),
(m_Flags & IS_MOVED) ? color : ReturnLayerColor( LAYER_DEVICE_BACKGROUND ), (m_Flags & IS_MOVED) ? color : ReturnLayerColor( LAYER_DEVICE_BACKGROUND ),
ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) ); ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) );
else if( fill == FILLED_SHAPE ) else if( fill == FILLED_SHAPE )
...@@ -236,6 +235,20 @@ void LIB_CIRCLE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, ...@@ -236,6 +235,20 @@ void LIB_CIRCLE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
} }
void LIB_CIRCLE::saveAttributes()
{
m_savedPos = m_Pos;
m_savedRadius = m_Radius;
}
void LIB_CIRCLE::restoreAttributes()
{
m_Pos = m_savedPos;
m_Radius = m_savedRadius;
}
EDA_Rect LIB_CIRCLE::GetBoundingBox() EDA_Rect LIB_CIRCLE::GetBoundingBox()
{ {
EDA_Rect rect; EDA_Rect rect;
...@@ -267,3 +280,69 @@ void LIB_CIRCLE::DisplayInfo( WinEDA_DrawFrame* aFrame ) ...@@ -267,3 +280,69 @@ void LIB_CIRCLE::DisplayInfo( WinEDA_DrawFrame* aFrame )
aFrame->AppendMsgPanel( _( "Bounding box" ), msg, BROWN ); aFrame->AppendMsgPanel( _( "Bounding box" ), msg, BROWN );
} }
void LIB_CIRCLE::BeginEdit( int aEditMode, const wxPoint aPosition )
{
wxCHECK_RET( ( aEditMode & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0,
wxT( "Invalid edit mode for LIB_CIRCLE object." ) );
if( aEditMode == IS_NEW )
{
m_Pos = m_initialPos = aPosition;
}
else if( aEditMode == IS_MOVED )
{
m_initialPos = m_Pos;
m_initialCursorPos = aPosition;
saveAttributes();
SetEraseLastDrawItem();
}
else if( aEditMode == IS_RESIZED )
{
saveAttributes();
SetEraseLastDrawItem();
}
m_Flags = aEditMode;
}
bool LIB_CIRCLE::ContinueEdit( const wxPoint aPosition )
{
wxCHECK_MSG( ( m_Flags & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0, false,
wxT( "Bad call to ContinueEdit(). LIB_CIRCLE is not being edited." ) );
return false;
}
void LIB_CIRCLE::EndEdit( const wxPoint& aPosition, bool aAbort )
{
wxCHECK_RET( ( m_Flags & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0,
wxT( "Bad call to EndEdit(). LIB_CIRCLE is not being edited." ) );
if( aAbort && !IsNew() )
restoreAttributes();
SetEraseLastDrawItem( false );
m_Flags = 0;
}
void LIB_CIRCLE::calcEdit( const wxPoint& aPosition )
{
if( m_Flags == IS_NEW || m_Flags == IS_RESIZED )
{
if( m_Flags == IS_NEW )
SetEraseLastDrawItem();
int dx = m_Pos.x - aPosition.x;
int dy = m_Pos.y - aPosition.y;
m_Radius = wxRound( sqrt( ( (double) dx * dx ) + ( (double) dy * dy ) ) );
}
else
{
Move( m_initialPos + aPosition - m_initialCursorPos );
}
}
...@@ -11,13 +11,39 @@ ...@@ -11,13 +11,39 @@
class LIB_CIRCLE : public LIB_DRAW_ITEM class LIB_CIRCLE : public LIB_DRAW_ITEM
{ {
int m_savedRadius; ///< Temporary storage of radius before editing begins.
/**
* Draws the arc.
*/
void drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOffset,
int aColor, int aDrawMode, void* aData, const TRANSFORM& aTransform );
/**
* See LIB_DRAW_ITEM::saveAttributes().
*/
void saveAttributes();
/**
* See LIB_DRAW_ITEM::restoreAttributes().
*/
void restoreAttributes();
/**
* Calculate the new circle at \a aPosition when editing.
*
* @param aPosition - The position to edit the circle in drawing coordinates.
*/
void calcEdit( const wxPoint& aPosition );
public: public:
int m_Radius; int m_Radius;
wxPoint m_Pos; /* Position or centre (Arc and Circle) or start point (segments) */ wxPoint m_Pos; /* Position or centre (Arc and Circle) or start point (segments) */
int m_Width; /* Line width */ int m_Width; /* Line width */
public: public:
LIB_CIRCLE(LIB_COMPONENT * aParent); LIB_CIRCLE( LIB_COMPONENT * aParent );
LIB_CIRCLE( const LIB_CIRCLE& aCircle ); LIB_CIRCLE( const LIB_CIRCLE& aCircle );
~LIB_CIRCLE() { } ~LIB_CIRCLE() { }
virtual wxString GetClass() const virtual wxString GetClass() const
...@@ -47,23 +73,34 @@ public: ...@@ -47,23 +73,34 @@ public:
* @param aPosRef - a wxPoint to test * @param aPosRef - a wxPoint to test
* @param aThreshold - max distance to this object (usually the half * @param aThreshold - max distance to this object (usually the half
* thickness of a line) * thickness of a line)
* @param aTransMat - the transform matrix * @param aTransform - the transform matrix
* @return true if the point aPosRef is near this object * @return true if the point aPosRef is near this object
*/ */
virtual bool HitTest( wxPoint aPosRef, int aThreshold, const int aTransMat[2][2] ); virtual bool HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform );
/** /**
* @return the size of the "pen" that be used to draw or plot this item * @return the size of the "pen" that be used to draw or plot this item
*/ */
virtual int GetPenSize( ); virtual int GetPenSize( );
void Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint &aOffset,
int aColor, int aDrawMode, void* aData,
const int aTransformMatrix[2][2] );
virtual EDA_Rect GetBoundingBox(); virtual EDA_Rect GetBoundingBox();
virtual void DisplayInfo( WinEDA_DrawFrame* aFrame ); virtual void DisplayInfo( WinEDA_DrawFrame* aFrame );
/**
* See LIB_DRAW_ITEM::BeginEdit().
*/
void BeginEdit( int aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) );
/**
* See LIB_DRAW_ITEM::ContinueEdit().
*/
bool ContinueEdit( const wxPoint aNextPoint );
/**
* See LIB_DRAW_ITEM::AbortEdit().
*/
void EndEdit( const wxPoint& aPosition, bool aAbort = false );
protected: protected:
virtual LIB_DRAW_ITEM* DoGenCopy(); virtual LIB_DRAW_ITEM* DoGenCopy();
...@@ -83,7 +120,7 @@ protected: ...@@ -83,7 +120,7 @@ protected:
virtual wxPoint DoGetPosition() { return m_Pos; } virtual wxPoint DoGetPosition() { return m_Pos; }
virtual void DoMirrorHorizontal( const wxPoint& aCenter ); virtual void DoMirrorHorizontal( const wxPoint& aCenter );
virtual void DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, virtual void DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
const int aTransform[2][2] ); const TRANSFORM& aTransform );
virtual int DoGetWidth() { return m_Width; } virtual int DoGetWidth() { return m_Width; }
virtual void DoSetWidth( int aWidth ) { m_Width = aWidth; } virtual void DoSetWidth( int aWidth ) { m_Width = aWidth; }
}; };
......
...@@ -4,17 +4,11 @@ ...@@ -4,17 +4,11 @@
#include "fctsys.h" #include "fctsys.h"
#include "gr_basic.h" #include "gr_basic.h"
#include "common.h"
#include "class_drawpanel.h" #include "class_drawpanel.h"
#include "plot_common.h" #include "wxstruct.h"
#include "drawtxt.h"
#include "trigo.h"
#include "bezier_curves.h"
#include "confirm.h"
#include "program.h"
#include "general.h"
#include "protos.h" #include "protos.h"
#include "general.h"
#include "lib_draw_item.h" #include "lib_draw_item.h"
const int fill_tab[3] = { 'N', 'F', 'f' }; const int fill_tab[3] = { 'N', 'F', 'f' };
...@@ -30,12 +24,13 @@ LIB_DRAW_ITEM::LIB_DRAW_ITEM( KICAD_T aType, ...@@ -30,12 +24,13 @@ LIB_DRAW_ITEM::LIB_DRAW_ITEM( KICAD_T aType,
FILL_T aFillType ) : FILL_T aFillType ) :
EDA_BaseStruct( aType ) EDA_BaseStruct( aType )
{ {
m_Unit = aUnit; m_Unit = aUnit;
m_Convert = aConvert; m_Convert = aConvert;
m_Fill = aFillType; m_Fill = aFillType;
m_Parent = (EDA_BaseStruct*) aComponent; m_Parent = (EDA_BaseStruct*) aComponent;
m_typeName = _( "Undefined" ); m_typeName = _( "Undefined" );
m_isFillable = false; m_isFillable = false;
m_eraseLastDrawItem = false;
} }
...@@ -111,3 +106,44 @@ bool LIB_DRAW_ITEM::operator<( const LIB_DRAW_ITEM& aOther ) const ...@@ -111,3 +106,44 @@ bool LIB_DRAW_ITEM::operator<( const LIB_DRAW_ITEM& aOther ) const
return ( DoCompare( aOther ) < 0 ); return ( DoCompare( aOther ) < 0 );
} }
void LIB_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOffset, int aColor,
int aDrawMode, void* aData, const TRANSFORM& aTransform )
{
if( InEditMode() )
{
// Temporarily disable filling while the item is being edited.
FILL_T fillMode = m_Fill;
int color = GetDefaultColor();
m_Fill = NO_FILL;
// Erase the old items using the previous attributes.
if( m_eraseLastDrawItem )
{
GRSetDrawMode( aDC, g_XorMode );
drawEditGraphics( &aPanel->m_ClipBox, aDC, color );
drawGraphic( aPanel, aDC, wxPoint( 0, 0 ), color, g_XorMode, aData, aTransform );
}
// Calculte the new attributes at the current cursor position.
calcEdit( aOffset );
// Draw the items using the new attributes.
drawEditGraphics( &aPanel->m_ClipBox, aDC, color );
drawGraphic( aPanel, aDC, wxPoint( 0, 0 ), color, g_XorMode, aData, aTransform );
m_Fill = fillMode;
}
else
{
drawGraphic( aPanel, aDC, aOffset, aColor, aDrawMode, aData, aTransform );
}
}
int LIB_DRAW_ITEM::GetDefaultColor()
{
return ReturnLayerColor( LAYER_DEVICE );
}
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#define _LIB_DRAW_ITEM_H_ #define _LIB_DRAW_ITEM_H_
#include "base_struct.h" #include "base_struct.h"
#include "transform.h"
#include <boost/ptr_container/ptr_vector.hpp> #include <boost/ptr_container/ptr_vector.hpp>
...@@ -20,6 +21,11 @@ class LIB_PIN; ...@@ -20,6 +21,11 @@ class LIB_PIN;
extern const int fill_tab[]; extern const int fill_tab[];
// Set KICAD_USE_LIB_OJBECT_EDIT to 1 to use build in ojbect editing mode.
#if !defined( KICAD_USE_LIB_OJBECT_EDIT )
#undef KICAD_USE_LIB_OJBECT_EDIT
#define KICAD_USE_LIB_OJBECT_EDIT 1
#endif
#define MINIMUM_SELECTION_DISTANCE 15 // Minimum selection distance in mils #define MINIMUM_SELECTION_DISTANCE 15 // Minimum selection distance in mils
...@@ -51,7 +57,53 @@ typedef std::vector< LIB_PIN* > LIB_PIN_LIST; ...@@ -51,7 +57,53 @@ typedef std::vector< LIB_PIN* > LIB_PIN_LIST;
*/ */
class LIB_DRAW_ITEM : public EDA_BaseStruct class LIB_DRAW_ITEM : public EDA_BaseStruct
{ {
wxPoint m_lastPosition; ///< Last position when moving the draw item. /**
* Draws the item.
*/
virtual void drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC,
const wxPoint& aOffset, int aColor,
int aDrawMode, void* aData, const TRANSFORM& aTransform ) = 0;
/**
* Draw any editing specific graphics when the item is being edited.
*
* @param aClipBox - Clip box of the current device context.
* @param aDC - The device context to draw on.
* @param aColor - The index of the color to draw.
*/
virtual void drawEditGraphics( EDA_Rect* aClipBox, wxDC* aDC, int aColor ) {}
/**
* Calculates the attributes of an item at \a aPosition when it is being edited.
*
* This method gets called by the Draw() method when the item is being edited. This
* probably should be a pure virtual method but bezier curves are not yet editable in
* the component library editor. Therefore, the default method does nothing.
*
* @param aPosition - The current mouse position in drawing coordinates.
*/
virtual void calcEdit( const wxPoint& aPosition ) {}
/**
* Save the current item attributes while editing.
*
* This method is used to save the drawing attributes of the item during editing.
* These values are restored when an edit is canceled by calling EndEdit().
*/
virtual void saveAttributes() {}
/**
* Restore the saved attributes when an existing item edit is cancelled.
*/
virtual void restoreAttributes() {}
bool m_eraseLastDrawItem; ///< Used when editing a new draw item to prevent drawing
///< artifacts.
protected:
wxPoint m_savedPos; ///< Temporary position when editng an existing item.
wxPoint m_initialPos; ///< Temporary position when moving an existing item.
wxPoint m_initialCursorPos; ///< Iniital cursor position at the begining of a move.
public: public:
/** /**
...@@ -93,7 +145,7 @@ public: ...@@ -93,7 +145,7 @@ public:
virtual ~LIB_DRAW_ITEM() { } virtual ~LIB_DRAW_ITEM() { }
/** /**
* Begin an editing a component library draw item in \a aEditMode at \a aStartPoint. * Begin an editing a component library draw item in \a aEditMode at \a aPosition.
* *
* This is used to start an editing action such as resize or move a draw object. * This is used to start an editing action such as resize or move a draw object.
* It typically would be called on a left click when a draw tool is selected in * It typically would be called on a left click when a draw tool is selected in
...@@ -103,30 +155,36 @@ public: ...@@ -103,30 +155,36 @@ public:
* *
* @param aEditMode - The editing mode being performed. See base_struct.h for a list * @param aEditMode - The editing mode being performed. See base_struct.h for a list
* of mode flags. * of mode flags.
* @param aStartPoint - The where the editing mode was started. This may or may not * @param aPosition - The position in drawing coordinates where the editing mode was
* be required depending on the item being edited and the edit * started. This may or may not be required depending on the item
* mode. * being edited and the edit mode.
*/ */
virtual void BeginEdit( int aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) ) {} virtual void BeginEdit( int aEditMode, const wxPoint aPosition = wxPoint( 0, 0 ) ) {}
/** /**
* Continue an edit in progress at \a aNextPoint. * Continue an edit in progress at \a aPosition.
* *
* This is used to perform the next action while editing a draw item. This would be * This is used to perform the next action while editing a draw item. This would be
* called for each additional left click when the mouse is captured while the item * called for each additional left click when the mouse is captured while the item
* is being edited. * is being edited.
*
* @param aPosition - The position of the mouse left click in drawing coordinates.
* @return True if additional mouse clicks are required to complete the edit in progress.
*/ */
virtual void ContinueEdit( const wxPoint aNextPoint ) {} virtual bool ContinueEdit( const wxPoint aPosition ) { return false; }
/** /**
* End an object editing action. * End an object editing action.
* *
* This is used to abort an edit action in progress initiated by BeginEdit(). * This is used to end or abort an edit action in progress initiated by BeginEdit().
*
* @param aPosition - The position of the last edit event in drawing coordinates.
* @param aAbort - Set to true to abort the current edit in progress.
*/ */
virtual void AbortEdit() { m_Flags = 0; } virtual void EndEdit( const wxPoint& aPosition, bool aAbort = false ) { m_Flags = 0; }
/** /**
* Draw a body item * Draw an item
* *
* @param aPanel - DrawPanel to use (can be null) mainly used for clipping * @param aPanel - DrawPanel to use (can be null) mainly used for clipping
* purposes * purposes
...@@ -140,11 +198,10 @@ public: ...@@ -140,11 +198,10 @@ public:
* to force no fill mode ( has meaning only for items what * to force no fill mode ( has meaning only for items what
* can be filled ). used in printing or moving objects mode * can be filled ). used in printing or moving objects mode
* or to pass reference to the lib component for pins * or to pass reference to the lib component for pins
* @param aTransformMatrix - Transform Matrix (rotation, mirror ..) * @param aTransform - Transform Matrix (rotation, mirror ..)
*/ */
virtual void Draw( WinEDA_DrawPanel * aPanel, wxDC * aDC, virtual void Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint &aOffset, int aColor,
const wxPoint &aOffset, int aColor, int aDrawMode, int aDrawMode, void* aData, const TRANSFORM& aTransform );
void* aData, const int aTransformMatrix[2][2] ) = 0;
/** /**
* @return the size of the "pen" that be used to draw or plot this item * @return the size of the "pen" that be used to draw or plot this item
...@@ -152,7 +209,7 @@ public: ...@@ -152,7 +209,7 @@ public:
virtual int GetPenSize() = 0; virtual int GetPenSize() = 0;
/** /**
* Write draw item object to /a aFile in "*.lib" format. * Write draw item object to \a aFile in "*.lib" format.
* *
* @param aFile - The file to write to. * @param aFile - The file to write to.
* @param aErrorMsg - Error message if write fails. * @param aErrorMsg - Error message if write fails.
...@@ -183,10 +240,10 @@ public: ...@@ -183,10 +240,10 @@ public:
* @param aPosRef - a wxPoint to test * @param aPosRef - a wxPoint to test
* @param aThreshold - max distance to this object (usually the half * @param aThreshold - max distance to this object (usually the half
* thickness of a line) * thickness of a line)
* @param aTransMat - the transform matrix * @param aTransform - the transform matrix
* @return - true if the point aPosRef is near this object * @return - true if the point aPosRef is near this object
*/ */
virtual bool HitTest( wxPoint aPosRef, int aThreshold, const int aTransMat[2][2] ) = 0; virtual bool HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform ) = 0;
/** /**
* @return the boundary box for this, in library coordinates * @return the boundary box for this, in library coordinates
...@@ -247,7 +304,7 @@ public: ...@@ -247,7 +304,7 @@ public:
bool Inside( EDA_Rect& aRect ) { return DoTestInside( aRect ); } bool Inside( EDA_Rect& aRect ) { return DoTestInside( aRect ); }
/** /**
* Move a draw object to a new /a aPosition. * Move a draw object to a new \a aPosition.
* *
* The real work is done by the DoMove method for each derived object type. * The real work is done by the DoMove method for each derived object type.
* *
...@@ -270,6 +327,11 @@ public: ...@@ -270,6 +327,11 @@ public:
DoMirrorHorizontal( aCenter ); DoMirrorHorizontal( aCenter );
} }
/**
* Rotate the draw item.
*/
virtual void Rotate() {}
/** /**
* Plot the draw item using the plot object. * Plot the draw item using the plot object.
* *
...@@ -278,8 +340,7 @@ public: ...@@ -278,8 +340,7 @@ public:
* @param aFill - Flag to indicate whether or not the object is filled. * @param aFill - Flag to indicate whether or not the object is filled.
* @param aTransform - The plot transform. * @param aTransform - The plot transform.
*/ */
void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, const TRANSFORM& aTransform )
const int aTransform[2][2] )
{ {
DoPlot( aPlotter, aOffset, aFill, aTransform ); DoPlot( aPlotter, aOffset, aFill, aTransform );
} }
...@@ -315,6 +376,27 @@ public: ...@@ -315,6 +376,27 @@ public:
* @return - True if the draw item has been added to the parent component. * @return - True if the draw item has been added to the parent component.
*/ */
bool IsNew() { return ( m_Flags & IS_NEW ) != 0; } bool IsNew() { return ( m_Flags & IS_NEW ) != 0; }
bool IsMoving() { return ( m_Flags & IS_MOVED ); }
bool IsResizing() { return ( m_Flags & IS_RESIZED ); }
/**
* Return the draw item editing mode status.
*
* @return - True if the item is being edited.
*/
bool InEditMode() { return ( m_Flags & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0; }
void SetEraseLastDrawItem( bool aErase = true ) { m_eraseLastDrawItem = aErase; }
virtual int GetDefaultColor();
void SetUnit( int aUnit ) { m_Unit = aUnit; }
int GetUnit() { return m_Unit; }
void SetConvert( int aConvert ) { m_Convert = aConvert; }
int GetConvert() { return m_Convert; }
protected: protected:
virtual LIB_DRAW_ITEM* DoGenCopy() = 0; virtual LIB_DRAW_ITEM* DoGenCopy() = 0;
...@@ -337,7 +419,7 @@ protected: ...@@ -337,7 +419,7 @@ protected:
virtual wxPoint DoGetPosition() = 0; virtual wxPoint DoGetPosition() = 0;
virtual void DoMirrorHorizontal( const wxPoint& aCenter ) = 0; virtual void DoMirrorHorizontal( const wxPoint& aCenter ) = 0;
virtual void DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, virtual void DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
const int aTransform[2][2] ) = 0; const TRANSFORM& aTransform ) = 0;
virtual int DoGetWidth() = 0; virtual int DoGetWidth() = 0;
virtual void DoSetWidth( int aWidth ) = 0; virtual void DoSetWidth( int aWidth ) = 0;
...@@ -354,16 +436,42 @@ protected: ...@@ -354,16 +436,42 @@ protected:
/*********************************************/ /*********************************************/
class LIB_TEXT : public LIB_DRAW_ITEM, public EDA_TextStruct class LIB_TEXT : public LIB_DRAW_ITEM, public EDA_TextStruct
{ {
int m_savedOrientation; ///< Temporary storage for orientation when editing.
bool m_rotate; ///< Flag to indicate a rotation occurred while editing.
/**
* Draw the polyline.
*/
void drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOffset,
int aColor, int aDrawMode, void* aData, const TRANSFORM& aTransform );
/**
* See LIB_DRAW_ITEM::saveAttributes().
*/
void saveAttributes();
/**
* See LIB_DRAW_ITEM::restoreAttributes().
*/
void restoreAttributes();
/**
* Calculate the text attributes ralative to \a aPosition while editing.
*
* @param aPosition - Edit position in drawing units.
*/
void calcEdit( const wxPoint& aPosition );
public: public:
LIB_TEXT(LIB_COMPONENT * aParent); LIB_TEXT( LIB_COMPONENT * aParent );
LIB_TEXT( const LIB_TEXT& aText ); LIB_TEXT( const LIB_TEXT& aText );
~LIB_TEXT() { } ~LIB_TEXT() { }
virtual wxString GetClass() const virtual wxString GetClass() const
{ {
return wxT( "LIB_TEXT" ); return wxT( "LIB_TEXT" );
} }
/** /**
* Write text object out to a FILE in "*.lib" format. * Write text object out to a FILE in "*.lib" format.
* *
...@@ -384,11 +492,10 @@ public: ...@@ -384,11 +492,10 @@ public:
/** /**
* @param aPosRef = a wxPoint to test, in eeschema coordinates * @param aPosRef = a wxPoint to test, in eeschema coordinates
* @param aThreshold = max distance to a segment * @param aThreshold = max distance to a segment
* @param aTransMat = the transform matrix * @param aTransform = the transform matrix
* @return true if the point aPosRef is near a segment * @return true if the point aPosRef is near a segment
*/ */
virtual bool HitTest( wxPoint aPosRef, int aThreshold, virtual bool HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform );
const int aTransMat[2][2] );
/** /**
* Test if the given rectangle intersects this object. * Test if the given rectangle intersects this object.
...@@ -408,14 +515,27 @@ public: ...@@ -408,14 +515,27 @@ public:
*/ */
virtual int GetPenSize( ); virtual int GetPenSize( );
void Draw( WinEDA_DrawPanel * aPanel, wxDC * aDC, const wxPoint &aOffset,
int aColor, int aDrawMode, void* aData,
const int aTransformMatrix[2][2] );
virtual void DisplayInfo( WinEDA_DrawFrame* aFrame ); virtual void DisplayInfo( WinEDA_DrawFrame* aFrame );
virtual EDA_Rect GetBoundingBox(); virtual EDA_Rect GetBoundingBox();
void Rotate();
/**
* See LIB_DRAW_ITEM::BeginEdit().
*/
void BeginEdit( int aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) );
/**
* See LIB_DRAW_ITEM::ContinueEdit().
*/
bool ContinueEdit( const wxPoint aNextPoint );
/**
* See LIB_DRAW_ITEM::AbortEdit().
*/
void EndEdit( const wxPoint& aPosition, bool aAbort = false );
protected: protected:
virtual LIB_DRAW_ITEM* DoGenCopy(); virtual LIB_DRAW_ITEM* DoGenCopy();
...@@ -437,7 +557,7 @@ protected: ...@@ -437,7 +557,7 @@ protected:
virtual wxPoint DoGetPosition() { return m_Pos; } virtual wxPoint DoGetPosition() { return m_Pos; }
virtual void DoMirrorHorizontal( const wxPoint& aCenter ); virtual void DoMirrorHorizontal( const wxPoint& aCenter );
virtual void DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, virtual void DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
const int aTransform[2][2] ); const TRANSFORM& aTransform );
virtual int DoGetWidth() { return m_Width; } virtual int DoGetWidth() { return m_Width; }
virtual void DoSetWidth( int aWidth ) { m_Width = aWidth; } virtual void DoSetWidth( int aWidth ) { m_Width = aWidth; }
}; };
......
...@@ -17,15 +17,16 @@ ...@@ -17,15 +17,16 @@
#include "general.h" #include "general.h"
#include "protos.h" #include "protos.h"
#include "class_libentry.h" #include "class_libentry.h"
#include "transform.h"
#include <wx/tokenzr.h> #include <wx/tokenzr.h>
#include <wx/stream.h> #include <wx/stream.h>
#include <wx/txtstrm.h> #include <wx/txtstrm.h>
/***************************/ /*******************/
/* class LibraryFieldEntry */ /* class LIB_FIELD */
/***************************/ /*******************/
/** /**
* a Field is a string linked to a component. * a Field is a string linked to a component.
...@@ -82,6 +83,8 @@ void LIB_FIELD::Init( int id ) ...@@ -82,6 +83,8 @@ void LIB_FIELD::Init( int id )
m_FieldId = id; m_FieldId = id;
m_Size.x = m_Size.y = DEFAULT_SIZE_TEXT; m_Size.x = m_Size.y = DEFAULT_SIZE_TEXT;
m_typeName = _( "Field" ); m_typeName = _( "Field" );
m_Orient = TEXT_ORIENT_HORIZ;
m_rotate = false;
// fields in RAM must always have names, because we are trying to get // fields in RAM must always have names, because we are trying to get
// less dependent on field ids and more dependent on names. // less dependent on field ids and more dependent on names.
...@@ -288,9 +291,8 @@ int LIB_FIELD::GetPenSize() ...@@ -288,9 +291,8 @@ int LIB_FIELD::GetPenSize()
* if aData not NULL, aData must point a wxString which is used instead of * if aData not NULL, aData must point a wxString which is used instead of
* the m_Text * the m_Text
*/ */
void LIB_FIELD::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, void LIB_FIELD::drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOffset,
const wxPoint& aOffset, int aColor, int aDrawMode, int aColor, int aDrawMode, void* aData, const TRANSFORM& aTransform )
void* aData, const int aTransformMatrix[2][2] )
{ {
wxPoint text_pos; wxPoint text_pos;
int color; int color;
...@@ -312,29 +314,22 @@ void LIB_FIELD::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, ...@@ -312,29 +314,22 @@ void LIB_FIELD::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
} }
if( color < 0 ) if( color < 0 )
{ color = GetDefaultColor();
switch( m_FieldId )
{
case REFERENCE:
color = ReturnLayerColor( LAYER_REFERENCEPART );
break;
case VALUE: text_pos = aTransform.TransformCoordinate( m_Pos ) + aOffset;
color = ReturnLayerColor( LAYER_VALUEPART );
break;
default: wxString text;
color = ReturnLayerColor( LAYER_FIELDS );
break; if( aData )
} text = *(wxString*)aData;
} else if( InEditMode() )
text = GetFullText( m_Unit );
else
text = m_Text;
text_pos = TransformCoordinate( aTransformMatrix, m_Pos ) + aOffset;
wxString* text = aData ? (wxString*)aData : &m_Text;
GRSetDrawMode( aDC, aDrawMode ); GRSetDrawMode( aDC, aDrawMode );
DrawGraphicText( aPanel, aDC, text_pos, (EDA_Colors) color, *text, DrawGraphicText( aPanel, aDC, text_pos, (EDA_Colors) color, text, m_Orient, m_Size,
m_Orient, m_Size, m_HJustify, m_VJustify, linewidth, m_HJustify, m_VJustify, linewidth, m_Italic, m_Bold );
m_Italic, m_Bold );
/* Set to one (1) to draw bounding box around field text to validate /* Set to one (1) to draw bounding box around field text to validate
* bounding box calculation. */ * bounding box calculation. */
...@@ -350,6 +345,20 @@ void LIB_FIELD::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, ...@@ -350,6 +345,20 @@ void LIB_FIELD::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
} }
void LIB_FIELD::saveAttributes()
{
m_savedPos = m_Pos;
m_savedOrientation = m_Orient;
}
void LIB_FIELD::restoreAttributes()
{
m_Pos = m_savedPos;
m_Orient = m_savedOrientation;
}
/** /**
* Function HitTest * Function HitTest
* tests if the given wxPoint is within the bounds of this object. * tests if the given wxPoint is within the bounds of this object.
...@@ -358,7 +367,7 @@ void LIB_FIELD::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, ...@@ -358,7 +367,7 @@ void LIB_FIELD::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
*/ */
bool LIB_FIELD::HitTest( const wxPoint& refPos ) bool LIB_FIELD::HitTest( const wxPoint& refPos )
{ {
return HitTest( refPos, 0, DefaultTransformMatrix ); return HitTest( refPos, 0, DefaultTransform );
} }
...@@ -369,8 +378,7 @@ bool LIB_FIELD::HitTest( const wxPoint& refPos ) ...@@ -369,8 +378,7 @@ bool LIB_FIELD::HitTest( const wxPoint& refPos )
* @param aThreshold = unused here (TextHitTest calculates its threshold ) * @param aThreshold = unused here (TextHitTest calculates its threshold )
* @param aTransMat = the transform matrix * @param aTransMat = the transform matrix
*/ */
bool LIB_FIELD::HitTest( wxPoint aPosRef, int aThreshold, bool LIB_FIELD::HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform )
const int aTransMat[2][2] )
{ {
int extraCharCount = 0; int extraCharCount = 0;
// Reference designator text has one or 2 additional character (displays // Reference designator text has one or 2 additional character (displays
...@@ -387,14 +395,14 @@ bool LIB_FIELD::HitTest( wxPoint aPosRef, int aThreshold, ...@@ -387,14 +395,14 @@ bool LIB_FIELD::HitTest( wxPoint aPosRef, int aThreshold,
} }
} }
wxPoint physicalpos = TransformCoordinate( aTransMat, m_Pos ); wxPoint physicalpos = aTransform.TransformCoordinate( m_Pos );
wxPoint tmp = m_Pos; wxPoint tmp = m_Pos;
m_Pos = physicalpos; m_Pos = physicalpos;
/* The text orientation may need to be flipped if the /* The text orientation may need to be flipped if the
* transformation matrix causes xy axes to be flipped. * transformation matrix causes xy axes to be flipped.
* this simple algo works only for schematic matrix (rot 90 or/and mirror) * this simple algo works only for schematic matrix (rot 90 or/and mirror)
*/ */
int t1 = ( aTransMat[0][0] != 0 ) ^ ( m_Orient != 0 ); int t1 = ( aTransform.x1 != 0 ) ^ ( m_Orient != 0 );
int orient = t1 ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT; int orient = t1 ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT;
EXCHG( m_Orient, orient ); EXCHG( m_Orient, orient );
...@@ -501,7 +509,7 @@ void LIB_FIELD::DoMirrorHorizontal( const wxPoint& center ) ...@@ -501,7 +509,7 @@ void LIB_FIELD::DoMirrorHorizontal( const wxPoint& center )
void LIB_FIELD::DoPlot( PLOTTER* plotter, const wxPoint& offset, bool fill, void LIB_FIELD::DoPlot( PLOTTER* plotter, const wxPoint& offset, bool fill,
const int transform[2][2] ) const TRANSFORM& aTransform )
{ {
} }
...@@ -544,3 +552,101 @@ EDA_Rect LIB_FIELD::GetBoundingBox() ...@@ -544,3 +552,101 @@ EDA_Rect LIB_FIELD::GetBoundingBox()
return rect; return rect;
} }
int LIB_FIELD::GetDefaultColor()
{
int color;
switch( m_FieldId )
{
case REFERENCE:
color = ReturnLayerColor( LAYER_REFERENCEPART );
break;
case VALUE:
color = ReturnLayerColor( LAYER_VALUEPART );
break;
default:
color = ReturnLayerColor( LAYER_FIELDS );
break;
}
return color;
}
void LIB_FIELD::Rotate()
{
if( InEditMode() )
{
m_rotate = true;
}
else
{
m_Orient = ( m_Orient == TEXT_ORIENT_VERT ) ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT;
}
}
void LIB_FIELD::BeginEdit( int aEditMode, const wxPoint aPosition )
{
wxCHECK_RET( ( aEditMode & ( IS_NEW | IS_MOVED ) ) != 0,
wxT( "Invalid edit mode for LIB_FIELD object." ) );
if( aEditMode == IS_MOVED )
{
m_initialPos = m_Pos;
m_initialCursorPos = aPosition;
saveAttributes();
SetEraseLastDrawItem();
}
else
{
m_Pos = aPosition;
}
m_Flags = aEditMode;
}
bool LIB_FIELD::ContinueEdit( const wxPoint aPosition )
{
wxCHECK_MSG( ( m_Flags & ( IS_NEW | IS_MOVED ) ) != 0, false,
wxT( "Bad call to ContinueEdit(). Text is not being edited." ) );
return false;
}
void LIB_FIELD::EndEdit( const wxPoint& aPosition, bool aAbort )
{
wxCHECK_RET( ( m_Flags & ( IS_NEW | IS_MOVED ) ) != 0,
wxT( "Bad call to EndEdit(). Text is not being edited." ) );
if( aAbort && !IsNew() )
restoreAttributes();
m_Flags = 0;
SetEraseLastDrawItem( false );
}
void LIB_FIELD::calcEdit( const wxPoint& aPosition )
{
if( m_rotate )
{
m_Orient = ( m_Orient == TEXT_ORIENT_VERT ) ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT;
m_rotate = false;
}
if( m_Flags == IS_NEW )
{
m_Pos = aPosition;
}
else if( m_Flags == IS_MOVED )
{
Move( m_initialPos + aPosition - m_initialCursorPos );
}
}
...@@ -18,6 +18,32 @@ ...@@ -18,6 +18,32 @@
*/ */
class LIB_FIELD : public LIB_DRAW_ITEM, public EDA_TextStruct class LIB_FIELD : public LIB_DRAW_ITEM, public EDA_TextStruct
{ {
int m_savedOrientation;
bool m_rotate; ///< Flag to indicate a rotation occurred while editing.
/**
* Draw the field.
*/
void drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOffset,
int aColor, int aDrawMode, void* aData, const TRANSFORM& aTransform );
/**
* See LIB_DRAW_ITEM::saveAttributes().
*/
void saveAttributes();
/**
* See LIB_DRAW_ITEM::restoreAttributes().
*/
void restoreAttributes();
/**
* Calculate the new circle at \a aPosition when editing.
*
* @param aPosition - The position to edit the circle in drawing coordinates.
*/
void calcEdit( const wxPoint& aPosition );
public: public:
int m_FieldId; ///< @see enum NumFieldType int m_FieldId; ///< @see enum NumFieldType
...@@ -67,10 +93,6 @@ public: ...@@ -67,10 +93,6 @@ public:
void SetFields( const std::vector <LIB_FIELD> aFields ); void SetFields( const std::vector <LIB_FIELD> aFields );
void Draw( WinEDA_DrawPanel * aPanel, wxDC * aDC, const wxPoint &aOffset,
int aColor, int aDrawMode, void* aData,
const int aTransformMatrix[2][2] );
/** /**
* Function IsVisible * Function IsVisible
* @return true is this field is visible, false if flagged invisible * @return true is this field is visible, false if flagged invisible
...@@ -98,11 +120,10 @@ public: ...@@ -98,11 +120,10 @@ public:
* @param aPosRef = a wxPoint to test * @param aPosRef = a wxPoint to test
* @param aThreshold = max distance to this object (usually the half * @param aThreshold = max distance to this object (usually the half
* thickness of a line) * thickness of a line)
* @param aTransMat = the transform matrix * @param aTransform = the transform matrix
* @return True if the point aPosRef is near this object * @return True if the point aPosRef is near this object
*/ */
virtual bool HitTest( wxPoint aPosRef, int aThreshold, virtual bool HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform );
const int aTransMat[2][2] );
void operator=( const LIB_FIELD& field ) void operator=( const LIB_FIELD& field )
{ {
...@@ -134,6 +155,25 @@ public: ...@@ -134,6 +155,25 @@ public:
*/ */
wxString GetFullText( int unit = 1 ); wxString GetFullText( int unit = 1 );
int GetDefaultColor();
/**
* See LIB_DRAW_ITEM::BeginEdit().
*/
void BeginEdit( int aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) );
/**
* See LIB_DRAW_ITEM::ContinueEdit().
*/
bool ContinueEdit( const wxPoint aNextPoint );
/**
* See LIB_DRAW_ITEM::AbortEdit().
*/
void EndEdit( const wxPoint& aPosition, bool aAbort = false );
void Rotate();
protected: protected:
virtual LIB_DRAW_ITEM* DoGenCopy(); virtual LIB_DRAW_ITEM* DoGenCopy();
...@@ -157,7 +197,7 @@ protected: ...@@ -157,7 +197,7 @@ protected:
virtual wxPoint DoGetPosition( void ) { return m_Pos; } virtual wxPoint DoGetPosition( void ) { return m_Pos; }
virtual void DoMirrorHorizontal( const wxPoint& center ); virtual void DoMirrorHorizontal( const wxPoint& center );
virtual void DoPlot( PLOTTER* plotter, const wxPoint& offset, bool fill, virtual void DoPlot( PLOTTER* plotter, const wxPoint& offset, bool fill,
const int transform[2][2] ); const TRANSFORM& aTransform );
virtual int DoGetWidth( void ) { return m_Width; } virtual int DoGetWidth( void ) { return m_Width; }
virtual void DoSetWidth( int width ) { m_Width = width; } virtual void DoSetWidth( int width ) { m_Width = width; }
}; };
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "general.h" #include "general.h"
#include "protos.h" #include "protos.h"
#include "lib_polyline.h" #include "lib_polyline.h"
#include "transform.h"
LIB_POLYLINE::LIB_POLYLINE( LIB_COMPONENT* aParent ) : LIB_POLYLINE::LIB_POLYLINE( LIB_COMPONENT* aParent ) :
...@@ -186,7 +187,7 @@ void LIB_POLYLINE::DoMirrorHorizontal( const wxPoint& aCenter ) ...@@ -186,7 +187,7 @@ void LIB_POLYLINE::DoMirrorHorizontal( const wxPoint& aCenter )
void LIB_POLYLINE::DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, void LIB_POLYLINE::DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
const int aTransform[2][2] ) const TRANSFORM& aTransform )
{ {
wxASSERT( aPlotter != NULL ); wxASSERT( aPlotter != NULL );
...@@ -200,7 +201,7 @@ void LIB_POLYLINE::DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill ...@@ -200,7 +201,7 @@ void LIB_POLYLINE::DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill
for( i = 0; i < m_PolyPoints.size(); i++ ) for( i = 0; i < m_PolyPoints.size(); i++ )
{ {
wxPoint pos = m_PolyPoints[i]; wxPoint pos = m_PolyPoints[i];
pos = TransformCoordinate( aTransform, pos ) + aOffset; pos = aTransform.TransformCoordinate(pos ) + aOffset;
Poly[i * 2] = pos.x; Poly[i * 2] = pos.x;
Poly[i * 2 + 1] = pos.y; Poly[i * 2 + 1] = pos.y;
} }
...@@ -232,9 +233,9 @@ int LIB_POLYLINE::GetPenSize() ...@@ -232,9 +233,9 @@ int LIB_POLYLINE::GetPenSize()
} }
void LIB_POLYLINE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, void LIB_POLYLINE::drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOffset,
const wxPoint& aOffset, int aColor, int aDrawMode, int aColor, int aDrawMode, void* aData,
void* aData, const int aTransformMatrix[2][2] ) const TRANSFORM& aTransform )
{ {
wxPoint pos1; wxPoint pos1;
int color = ReturnLayerColor( LAYER_DEVICE ); int color = ReturnLayerColor( LAYER_DEVICE );
...@@ -273,8 +274,7 @@ void LIB_POLYLINE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, ...@@ -273,8 +274,7 @@ void LIB_POLYLINE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ ) for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ )
{ {
Buf_Poly_Drawings[ii] = TransformCoordinate( aTransformMatrix, Buf_Poly_Drawings[ii] = aTransform.TransformCoordinate( m_PolyPoints[ii] ) + aOffset;
m_PolyPoints[ii] ) + aOffset;
} }
FILL_T fill = aData ? NO_FILL : m_Fill; FILL_T fill = aData ? NO_FILL : m_Fill;
...@@ -306,6 +306,18 @@ void LIB_POLYLINE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, ...@@ -306,6 +306,18 @@ void LIB_POLYLINE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
} }
void LIB_POLYLINE::saveAttributes()
{
m_savedPolyPoints = m_PolyPoints;
}
void LIB_POLYLINE::restoreAttributes()
{
m_PolyPoints = m_savedPolyPoints;
}
/** /**
* Function HitTest * Function HitTest
* tests if the given wxPoint is within the bounds of this object. * tests if the given wxPoint is within the bounds of this object.
...@@ -319,7 +331,7 @@ bool LIB_POLYLINE::HitTest( const wxPoint& aRefPos ) ...@@ -319,7 +331,7 @@ bool LIB_POLYLINE::HitTest( const wxPoint& aRefPos )
// Have a minimal tolerance for hit test // Have a minimal tolerance for hit test
if( mindist < MINIMUM_SELECTION_DISTANCE ) if( mindist < MINIMUM_SELECTION_DISTANCE )
mindist = MINIMUM_SELECTION_DISTANCE; mindist = MINIMUM_SELECTION_DISTANCE;
return HitTest( aRefPos, mindist, DefaultTransformMatrix ); return HitTest( aRefPos, mindist, DefaultTransform );
} }
...@@ -329,14 +341,14 @@ bool LIB_POLYLINE::HitTest( const wxPoint& aRefPos ) ...@@ -329,14 +341,14 @@ bool LIB_POLYLINE::HitTest( const wxPoint& aRefPos )
* @param aThreshold = max distance to a segment * @param aThreshold = max distance to a segment
* @param aTransMat = the transform matrix * @param aTransMat = the transform matrix
*/ */
bool LIB_POLYLINE::HitTest( wxPoint aPosRef, int aThreshold, const int aTransMat[2][2] ) bool LIB_POLYLINE::HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform )
{ {
wxPoint ref, start, end; wxPoint ref, start, end;
for( unsigned ii = 1; ii < GetCornerCount(); ii++ ) for( unsigned ii = 1; ii < GetCornerCount(); ii++ )
{ {
start = TransformCoordinate( aTransMat, m_PolyPoints[ii - 1] ); start = aTransform.TransformCoordinate( m_PolyPoints[ii - 1] );
end = TransformCoordinate( aTransMat, m_PolyPoints[ii] ); end = aTransform.TransformCoordinate( m_PolyPoints[ii] );
if( TestSegmentHit( aPosRef, start, end, aThreshold ) ) if( TestSegmentHit( aPosRef, start, end, aThreshold ) )
return true; return true;
...@@ -373,6 +385,22 @@ EDA_Rect LIB_POLYLINE::GetBoundingBox() ...@@ -373,6 +385,22 @@ EDA_Rect LIB_POLYLINE::GetBoundingBox()
} }
void LIB_POLYLINE::DeleteSegment( const wxPoint aPosition )
{
// First segment is kept, only its end point is changed
while( GetCornerCount() > 2 )
{
m_PolyPoints.pop_back();
if( m_PolyPoints[ GetCornerCount() - 1 ] != aPosition )
{
m_PolyPoints[ GetCornerCount() - 1 ] = aPosition;
break;
}
}
}
void LIB_POLYLINE::DisplayInfo( WinEDA_DrawFrame* aFrame ) void LIB_POLYLINE::DisplayInfo( WinEDA_DrawFrame* aFrame )
{ {
wxString msg; wxString msg;
...@@ -380,8 +408,7 @@ void LIB_POLYLINE::DisplayInfo( WinEDA_DrawFrame* aFrame ) ...@@ -380,8 +408,7 @@ void LIB_POLYLINE::DisplayInfo( WinEDA_DrawFrame* aFrame )
LIB_DRAW_ITEM::DisplayInfo( aFrame ); LIB_DRAW_ITEM::DisplayInfo( aFrame );
msg = ReturnStringFromValue( g_UserUnit, m_Width, msg = ReturnStringFromValue( g_UserUnit, m_Width, EESCHEMA_INTERNAL_UNIT, true );
EESCHEMA_INTERNAL_UNIT, true );
aFrame->AppendMsgPanel(_( "Line width" ), msg, BLUE ); aFrame->AppendMsgPanel(_( "Line width" ), msg, BLUE );
...@@ -390,3 +417,108 @@ void LIB_POLYLINE::DisplayInfo( WinEDA_DrawFrame* aFrame ) ...@@ -390,3 +417,108 @@ void LIB_POLYLINE::DisplayInfo( WinEDA_DrawFrame* aFrame )
aFrame->AppendMsgPanel( _( "Bounding box" ), msg, BROWN ); aFrame->AppendMsgPanel( _( "Bounding box" ), msg, BROWN );
} }
void LIB_POLYLINE::BeginEdit( int aEditMode, const wxPoint aPosition )
{
wxCHECK_RET( ( aEditMode & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0,
wxT( "Invalid edit mode for LIB_POLYLINE object." ) );
if( aEditMode == IS_NEW )
{
m_PolyPoints.push_back( aPosition ); // Start point of first segment.
m_PolyPoints.push_back( aPosition ); // End point of first segment.
}
else if( aEditMode == IS_RESIZED )
{
saveAttributes();
// Drag one edge point of the polyline
// Find the nearest edge point to be dragged
wxPoint startPoint = m_PolyPoints[0];
// Begin with the first list point as nearest point
int index = 0;
m_ModifyIndex = 0;
m_initialPos = startPoint;
// First distance is the current minimum distance
int distanceMin = (aPosition - startPoint).x * (aPosition - startPoint).x
+ (aPosition - startPoint).y * (aPosition - startPoint).y;
// Find the right index of the point to be dragged
BOOST_FOREACH( wxPoint point, m_PolyPoints )
{
int distancePoint = (aPosition - point).x * (aPosition - point).x +
(aPosition - point).y * (aPosition - point).y;
if( distancePoint < distanceMin )
{
// Save point.
m_initialPos = point;
m_ModifyIndex = index;
distanceMin = distancePoint;
break;
}
index++;
}
SetEraseLastDrawItem();
}
else if( aEditMode == IS_MOVED )
{
m_initialCursorPos = aPosition;
m_initialPos = m_PolyPoints[0];
saveAttributes();
SetEraseLastDrawItem();
}
m_Flags = aEditMode;
}
bool LIB_POLYLINE::ContinueEdit( const wxPoint aPosition )
{
wxCHECK_MSG( ( m_Flags & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0, false,
wxT( "Bad call to ContinueEdit(). LIB_POLYLINE is not being edited." ) );
if( m_Flags == IS_NEW )
{
m_PolyPoints.push_back( aPosition );
return true;
}
return false;
}
void LIB_POLYLINE::EndEdit( const wxPoint& aPosition, bool aAbort )
{
wxCHECK_RET( ( m_Flags & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0,
wxT( "Bad call to EndEdit(). LIB_POLYLINE is not being edited." ) );
if( aAbort && !IsNew() )
restoreAttributes();
m_Flags = 0;
SetEraseLastDrawItem( false );
}
void LIB_POLYLINE::calcEdit( const wxPoint& aPosition )
{
if( m_Flags == IS_NEW )
{
m_PolyPoints[ GetCornerCount() - 1 ] = aPosition;
SetEraseLastDrawItem();
}
else if( m_Flags == IS_RESIZED )
{
m_PolyPoints[ m_ModifyIndex ] = aPosition;
}
else if( m_Flags == IS_MOVED )
{
Move( m_initialPos + aPosition - m_initialCursorPos );
}
}
...@@ -11,13 +11,38 @@ ...@@ -11,13 +11,38 @@
class LIB_POLYLINE : public LIB_DRAW_ITEM class LIB_POLYLINE : public LIB_DRAW_ITEM
{ {
std::vector<wxPoint> m_savedPolyPoints;
/**
* Draw the polyline.
*/
void drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOffset,
int aColor, int aDrawMode, void* aData, const TRANSFORM& aTransform );
/**
* See LIB_DRAW_ITEM::saveAttributes().
*/
void saveAttributes();
/**
* See LIB_DRAW_ITEM::restoreAttributes().
*/
void restoreAttributes();
/**
* Calculate the polyline attributes ralative to \a aPosition while editing.
*
* @param aPosition - Edit position in drawing units.
*/
void calcEdit( const wxPoint& aPosition );
public: public:
int m_Width; /* Line width */ int m_Width; /* Line width */
std::vector<wxPoint> m_PolyPoints; // list of points (>= 2) std::vector<wxPoint> m_PolyPoints; // list of points (>= 2)
int m_ModifyIndex; // Index of the polyline point to modify int m_ModifyIndex; // Index of the polyline point to modify
public: public:
LIB_POLYLINE(LIB_COMPONENT * aParent); LIB_POLYLINE( LIB_COMPONENT * aParent );
LIB_POLYLINE( const LIB_POLYLINE& aPolyline ); LIB_POLYLINE( const LIB_POLYLINE& aPolyline );
~LIB_POLYLINE() { } ~LIB_POLYLINE() { }
...@@ -38,6 +63,11 @@ public: ...@@ -38,6 +63,11 @@ public:
void AddPoint( const wxPoint& aPoint ); void AddPoint( const wxPoint& aPoint );
/**
* Delete the segment at \a aPosition.
*/
void DeleteSegment( const wxPoint aPosition );
/** /**
* @return the number of corners * @return the number of corners
*/ */
...@@ -54,11 +84,10 @@ public: ...@@ -54,11 +84,10 @@ public:
/** /**
* @param aPosRef = a wxPoint to test * @param aPosRef = a wxPoint to test
* @param aThreshold = max distance to a segment * @param aThreshold = max distance to a segment
* @param aTransMat = the transform matrix * @param aTransform = the transform matrix
* @return true if the point aPosRef is near a segment * @return true if the point aPosRef is near a segment
*/ */
virtual bool HitTest( wxPoint aPosRef, int aThreshold, virtual bool HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform );
const int aTransMat[2][2] );
/** /**
* @return the boundary box for this, in library coordinates * @return the boundary box for this, in library coordinates
...@@ -70,12 +99,23 @@ public: ...@@ -70,12 +99,23 @@ public:
*/ */
virtual int GetPenSize( ); virtual int GetPenSize( );
void Draw( WinEDA_DrawPanel * aPanel, wxDC * aDC, const wxPoint &aOffset,
int aColor, int aDrawMode, void* aData,
const int aTransformMatrix[2][2] );
virtual void DisplayInfo( WinEDA_DrawFrame* aFrame ); virtual void DisplayInfo( WinEDA_DrawFrame* aFrame );
/**
* See LIB_DRAW_ITEM::BeginEdit().
*/
void BeginEdit( int aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) );
/**
* See LIB_DRAW_ITEM::ContinueEdit().
*/
bool ContinueEdit( const wxPoint aNextPoint );
/**
* See LIB_DRAW_ITEM::AbortEdit().
*/
void EndEdit( const wxPoint& aPosition, bool aAbort = false );
protected: protected:
virtual LIB_DRAW_ITEM* DoGenCopy(); virtual LIB_DRAW_ITEM* DoGenCopy();
...@@ -94,10 +134,10 @@ protected: ...@@ -94,10 +134,10 @@ protected:
virtual wxPoint DoGetPosition() { return m_PolyPoints[0]; } virtual wxPoint DoGetPosition() { return m_PolyPoints[0]; }
virtual void DoMirrorHorizontal( const wxPoint& aCenter ); virtual void DoMirrorHorizontal( const wxPoint& aCenter );
virtual void DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, virtual void DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
const int aTransform[2][2] ); const TRANSFORM& aTransform );
virtual int DoGetWidth() { return m_Width; } virtual int DoGetWidth() { return m_Width; }
virtual void DoSetWidth( int aWidth ) { m_Width = aWidth; } virtual void DoSetWidth( int aWidth ) { m_Width = aWidth; }
}; };
#endif // _LIB_POLYLIN_H_ #endif // _LIB_POLYLINE_H_
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "general.h" #include "general.h"
#include "protos.h" #include "protos.h"
#include "lib_rectangle.h" #include "lib_rectangle.h"
#include "transform.h"
LIB_RECTANGLE::LIB_RECTANGLE( LIB_COMPONENT* aParent ) : LIB_RECTANGLE::LIB_RECTANGLE( LIB_COMPONENT* aParent ) :
...@@ -141,12 +142,12 @@ void LIB_RECTANGLE::DoMirrorHorizontal( const wxPoint& aCenter ) ...@@ -141,12 +142,12 @@ void LIB_RECTANGLE::DoMirrorHorizontal( const wxPoint& aCenter )
void LIB_RECTANGLE::DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, void LIB_RECTANGLE::DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
const int aTransform[2][2] ) const TRANSFORM& aTransform )
{ {
wxASSERT( aPlotter != NULL ); wxASSERT( aPlotter != NULL );
wxPoint pos = TransformCoordinate( aTransform, m_Pos ) + aOffset; wxPoint pos = aTransform.TransformCoordinate( m_Pos ) + aOffset;
wxPoint end = TransformCoordinate( aTransform, m_End ) + aOffset; wxPoint end = aTransform.TransformCoordinate( m_End ) + aOffset;
if( aFill && m_Fill == FILLED_WITH_BG_BODYCOLOR ) if( aFill && m_Fill == FILLED_WITH_BG_BODYCOLOR )
{ {
...@@ -167,9 +168,9 @@ int LIB_RECTANGLE::GetPenSize() ...@@ -167,9 +168,9 @@ int LIB_RECTANGLE::GetPenSize()
return ( m_Width == 0 ) ? g_DrawDefaultLineThickness : m_Width; return ( m_Width == 0 ) ? g_DrawDefaultLineThickness : m_Width;
} }
void LIB_RECTANGLE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, void LIB_RECTANGLE::drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC,
const wxPoint& aOffset, int aColor, int aDrawMode, const wxPoint& aOffset, int aColor, int aDrawMode,
void* aData, const int aTransformMatrix[2][2] ) void* aData, const TRANSFORM& aTransform )
{ {
wxPoint pos1, pos2; wxPoint pos1, pos2;
...@@ -183,8 +184,8 @@ void LIB_RECTANGLE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, ...@@ -183,8 +184,8 @@ void LIB_RECTANGLE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
else else
color = aColor; color = aColor;
pos1 = TransformCoordinate( aTransformMatrix, m_Pos ) + aOffset; pos1 = aTransform.TransformCoordinate( m_Pos ) + aOffset;
pos2 = TransformCoordinate( aTransformMatrix, m_End ) + aOffset; pos2 = aTransform.TransformCoordinate( m_End ) + aOffset;
FILL_T fill = aData ? NO_FILL : m_Fill; FILL_T fill = aData ? NO_FILL : m_Fill;
if( aColor >= 0 ) if( aColor >= 0 )
...@@ -213,6 +214,20 @@ void LIB_RECTANGLE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, ...@@ -213,6 +214,20 @@ void LIB_RECTANGLE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
} }
void LIB_RECTANGLE::saveAttributes()
{
m_savedPos = m_Pos;
m_savedEndPos = m_End;
}
void LIB_RECTANGLE::restoreAttributes()
{
m_Pos = m_savedPos;
m_End = m_savedEndPos;
}
void LIB_RECTANGLE::DisplayInfo( WinEDA_DrawFrame* aFrame ) void LIB_RECTANGLE::DisplayInfo( WinEDA_DrawFrame* aFrame )
{ {
wxString msg; wxString msg;
...@@ -250,7 +265,7 @@ bool LIB_RECTANGLE::HitTest( const wxPoint& aRefPoint ) ...@@ -250,7 +265,7 @@ bool LIB_RECTANGLE::HitTest( const wxPoint& aRefPoint )
if( mindist < MINIMUM_SELECTION_DISTANCE ) if( mindist < MINIMUM_SELECTION_DISTANCE )
mindist = MINIMUM_SELECTION_DISTANCE; mindist = MINIMUM_SELECTION_DISTANCE;
return HitTest( aRefPoint, mindist, DefaultTransformMatrix ); return HitTest( aRefPoint, mindist, DefaultTransform );
} }
...@@ -261,10 +276,10 @@ bool LIB_RECTANGLE::HitTest( const wxPoint& aRefPoint ) ...@@ -261,10 +276,10 @@ bool LIB_RECTANGLE::HitTest( const wxPoint& aRefPoint )
* of a line) * of a line)
* @param aTransMat = the transform matrix * @param aTransMat = the transform matrix
*/ */
bool LIB_RECTANGLE::HitTest( wxPoint aRefPoint, int aThreshold, const int aTransMat[2][2] ) bool LIB_RECTANGLE::HitTest( wxPoint aRefPoint, int aThreshold, const TRANSFORM& aTransform )
{ {
wxPoint actualStart = TransformCoordinate( aTransMat, m_Pos ); wxPoint actualStart = aTransform.TransformCoordinate( m_Pos );
wxPoint actualEnd = TransformCoordinate( aTransMat, m_End ); wxPoint actualEnd = aTransform.TransformCoordinate( m_End );
// locate lower segment // locate lower segment
wxPoint start, end; wxPoint start, end;
...@@ -296,3 +311,105 @@ bool LIB_RECTANGLE::HitTest( wxPoint aRefPoint, int aThreshold, const int aTrans ...@@ -296,3 +311,105 @@ bool LIB_RECTANGLE::HitTest( wxPoint aRefPoint, int aThreshold, const int aTrans
return false; return false;
} }
void LIB_RECTANGLE::BeginEdit( int aEditMode, const wxPoint aPosition )
{
wxCHECK_RET( ( aEditMode & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0,
wxT( "Invalid edit mode for LIB_RECTANGLE object." ) );
if( aEditMode == IS_NEW )
{
m_Pos = m_End = aPosition;
}
else if( aEditMode == IS_RESIZED )
{
m_isStartPointSelected = abs( m_Pos.x - aPosition.x ) < MINIMUM_SELECTION_DISTANCE
|| abs( m_Pos.y - aPosition.y ) < MINIMUM_SELECTION_DISTANCE;
if( m_isStartPointSelected )
{
m_isWidthLocked = abs( m_Pos.x - aPosition.x ) >= MINIMUM_SELECTION_DISTANCE;
m_isHeightLocked = abs( m_Pos.y - aPosition.y ) >= MINIMUM_SELECTION_DISTANCE;
}
else
{
m_isWidthLocked = abs( m_End.x - aPosition.x ) >= MINIMUM_SELECTION_DISTANCE;
m_isHeightLocked = abs( m_End.y - aPosition.y ) >= MINIMUM_SELECTION_DISTANCE;
}
saveAttributes();
SetEraseLastDrawItem();
}
else if( aEditMode == IS_MOVED )
{
m_initialPos = m_Pos;
m_initialCursorPos = aPosition;
saveAttributes();
SetEraseLastDrawItem();
}
m_Flags = aEditMode;
}
bool LIB_RECTANGLE::ContinueEdit( const wxPoint aPosition )
{
wxCHECK_MSG( ( m_Flags & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0, false,
wxT( "Bad call to ContinueEdit(). LIB_RECTANGLE is not being edited." ) );
return false;
}
void LIB_RECTANGLE::EndEdit( const wxPoint& aPosition, bool aAbort )
{
wxCHECK_RET( ( m_Flags & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0,
wxT( "Bad call to EndEdit(). LIB_RECTANGLE is not being edited." ) );
if( aAbort && !IsNew() )
restoreAttributes();
m_Flags = 0;
m_isHeightLocked = false;
m_isWidthLocked = false;
SetEraseLastDrawItem( false );
}
void LIB_RECTANGLE::calcEdit( const wxPoint& aPosition )
{
if( m_Flags == IS_NEW )
{
m_End = aPosition;
SetEraseLastDrawItem();
}
else if( m_Flags == IS_RESIZED )
{
if( m_isHeightLocked )
{
if( m_isStartPointSelected )
m_Pos.x = aPosition.x;
else
m_End.x = aPosition.x;
}
else if( m_isWidthLocked )
{
if( m_isStartPointSelected )
m_Pos.y = aPosition.y;
else
m_End.y = aPosition.y;
}
else
{
if( m_isStartPointSelected )
m_Pos = aPosition;
else
m_End = aPosition;
}
}
else if( m_Flags == IS_MOVED )
{
Move( m_initialPos + aPosition - m_initialCursorPos );
}
}
...@@ -11,6 +11,31 @@ ...@@ -11,6 +11,31 @@
class LIB_RECTANGLE : public LIB_DRAW_ITEM class LIB_RECTANGLE : public LIB_DRAW_ITEM
{ {
wxPoint m_savedEndPos; ///< Tempory storage of the current end position before editing.
/**
* Draw the rectangle.
*/
void drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOffset,
int aColor, int aDrawMode, void* aData, const TRANSFORM& aTransform );
/**
* See LIB_DRAW_ITEM::saveAttributes().
*/
void saveAttributes();
/**
* See LIB_DRAW_ITEM::restoreAttributes().
*/
void restoreAttributes();
/**
* Calculate the rectangle attrubites ralative to \a aPosition while editing.
*
* @param aPosition - Edit position in drawing units.
*/
void calcEdit( const wxPoint& aPosition );
public: public:
wxPoint m_End; /* Rectangle end point. */ wxPoint m_End; /* Rectangle end point. */
wxPoint m_Pos; /* Rectangle start point. */ wxPoint m_Pos; /* Rectangle start point. */
...@@ -20,7 +45,7 @@ public: ...@@ -20,7 +45,7 @@ public:
bool m_isStartPointSelected; /* Flag: is the upper left edge selected ? */ bool m_isStartPointSelected; /* Flag: is the upper left edge selected ? */
public: public:
LIB_RECTANGLE(LIB_COMPONENT * aParent); LIB_RECTANGLE( LIB_COMPONENT * aParent );
LIB_RECTANGLE( const LIB_RECTANGLE& aRect ); LIB_RECTANGLE( const LIB_RECTANGLE& aRect );
~LIB_RECTANGLE() { } ~LIB_RECTANGLE() { }
virtual wxString GetClass() const virtual wxString GetClass() const
...@@ -50,23 +75,34 @@ public: ...@@ -50,23 +75,34 @@ public:
* @param aPosRef - a wxPoint to test * @param aPosRef - a wxPoint to test
* @param aThreshold - max distance to this object (usually the half * @param aThreshold - max distance to this object (usually the half
* thickness of a line) * thickness of a line)
* @param aTransMat - the transform matrix * @param aTransform - the transform matrix
* @return true if the point aPosRef is near this object * @return true if the point aPosRef is near this object
*/ */
virtual bool HitTest( wxPoint aPosRef, int aThreshold, const int aTransMat[2][2] ); virtual bool HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform );
/** /**
* @return the size of the "pen" that be used to draw or plot this item * @return the size of the "pen" that be used to draw or plot this item
*/ */
virtual int GetPenSize( ); virtual int GetPenSize( );
void Draw( WinEDA_DrawPanel * aPanel, wxDC * aDC, const wxPoint &aOffset,
int aColor, int aDrawMode, void* aData,
const int aTransformMatrix[2][2] );
virtual EDA_Rect GetBoundingBox(); virtual EDA_Rect GetBoundingBox();
virtual void DisplayInfo( WinEDA_DrawFrame* aFrame ); virtual void DisplayInfo( WinEDA_DrawFrame* aFrame );
/**
* See LIB_DRAW_ITEM::BeginEdit().
*/
void BeginEdit( int aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) );
/**
* See LIB_DRAW_ITEM::ContinueEdit().
*/
bool ContinueEdit( const wxPoint aNextPoint );
/**
* See LIB_DRAW_ITEM::AbortEdit().
*/
void EndEdit( const wxPoint& aPosition, bool aAbort = false );
protected: protected:
virtual LIB_DRAW_ITEM* DoGenCopy(); virtual LIB_DRAW_ITEM* DoGenCopy();
...@@ -87,7 +123,7 @@ protected: ...@@ -87,7 +123,7 @@ protected:
virtual wxPoint DoGetPosition() { return m_Pos; } virtual wxPoint DoGetPosition() { return m_Pos; }
virtual void DoMirrorHorizontal( const wxPoint& aCenter ); virtual void DoMirrorHorizontal( const wxPoint& aCenter );
virtual void DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, virtual void DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
const int aTransform[2][2] ); const TRANSFORM& aTransform );
virtual int DoGetWidth() { return m_Width; } virtual int DoGetWidth() { return m_Width; }
virtual void DoSetWidth( int aWidth ) { m_Width = aWidth; } virtual void DoSetWidth( int aWidth ) { m_Width = aWidth; }
}; };
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "lib_draw_item.h" #include "lib_draw_item.h"
#include "general.h" #include "general.h"
#include "protos.h" #include "protos.h"
#include "transform.h"
LIB_TEXT::LIB_TEXT(LIB_COMPONENT * aParent) : LIB_TEXT::LIB_TEXT(LIB_COMPONENT * aParent) :
...@@ -27,6 +28,7 @@ LIB_TEXT::LIB_TEXT(LIB_COMPONENT * aParent) : ...@@ -27,6 +28,7 @@ LIB_TEXT::LIB_TEXT(LIB_COMPONENT * aParent) :
{ {
m_Size = wxSize( 50, 50 ); m_Size = wxSize( 50, 50 );
m_typeName = _( "Text" ); m_typeName = _( "Text" );
m_rotate = false;
} }
...@@ -38,9 +40,8 @@ bool LIB_TEXT::Save( FILE* ExportFile ) ...@@ -38,9 +40,8 @@ bool LIB_TEXT::Save( FILE* ExportFile )
// changed to '~' // changed to '~'
text.Replace( wxT( " " ), wxT( "~" ) ); text.Replace( wxT( " " ), wxT( "~" ) );
if( fprintf( ExportFile, "T %d %d %d %d %d %d %d %s ", m_Orient, if( fprintf( ExportFile, "T %d %d %d %d %d %d %d %s ", m_Orient, m_Pos.x, m_Pos.y,
m_Pos.x, m_Pos.y, m_Size.x, m_Attributs, m_Unit, m_Convert, m_Size.x, m_Attributs, m_Unit, m_Convert, CONV_TO_UTF8( text ) ) < 0 )
CONV_TO_UTF8( text ) ) < 0 )
return false; return false;
if( fprintf( ExportFile, " %s %d", m_Italic ? "Italic" : "Normal", if( fprintf( ExportFile, " %s %d", m_Italic ? "Italic" : "Normal",
( m_Bold > 0 ) ? 1 : 0 ) < 0 ) ( m_Bold > 0 ) ? 1 : 0 ) < 0 )
...@@ -82,8 +83,7 @@ bool LIB_TEXT::Load( char* line, wxString& errorMsg ) ...@@ -82,8 +83,7 @@ bool LIB_TEXT::Load( char* line, wxString& errorMsg )
if( cnt < 8 ) if( cnt < 8 )
{ {
errorMsg.Printf( _( "text only had %d parameters of the required 8" ), errorMsg.Printf( _( "text only had %d parameters of the required 8" ), cnt );
cnt );
return false; return false;
} }
...@@ -141,7 +141,7 @@ bool LIB_TEXT::Load( char* line, wxString& errorMsg ) ...@@ -141,7 +141,7 @@ bool LIB_TEXT::Load( char* line, wxString& errorMsg )
*/ */
bool LIB_TEXT::HitTest( const wxPoint& refPos ) bool LIB_TEXT::HitTest( const wxPoint& refPos )
{ {
return HitTest( refPos, 0, DefaultTransformMatrix ); return HitTest( refPos, 0, DefaultTransform );
} }
...@@ -151,20 +151,20 @@ bool LIB_TEXT::HitTest( const wxPoint& refPos ) ...@@ -151,20 +151,20 @@ bool LIB_TEXT::HitTest( const wxPoint& refPos )
* @param aThreshold = unused here (TextHitTest calculates its threshold ) * @param aThreshold = unused here (TextHitTest calculates its threshold )
* @param aTransMat = the transform matrix * @param aTransMat = the transform matrix
*/ */
bool LIB_TEXT::HitTest( wxPoint aPosRef, int aThreshold, bool LIB_TEXT::HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform )
const int aTransMat[2][2] )
{ {
wxPoint physicalpos = TransformCoordinate( aTransMat, m_Pos ); wxPoint physicalpos = aTransform.TransformCoordinate( m_Pos );
wxPoint tmp = m_Pos; wxPoint tmp = m_Pos;
m_Pos = physicalpos; m_Pos = physicalpos;
/* The text orientation may need to be flipped if the /* The text orientation may need to be flipped if the
* transformation matrix causes xy axes to be flipped. * transformation matrix causes xy axes to be flipped.
* this simple algo works only for schematic matrix (rot 90 or/and mirror) * this simple algo works only for schematic matrix (rot 90 or/and mirror)
*/ */
int t1 = ( aTransMat[0][0] != 0 ) ^ ( m_Orient != 0 ); int t1 = ( aTransform.x1 != 0 ) ^ ( m_Orient != 0 );
int orient = t1 ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT; int orient = t1 ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT;
EXCHG( m_Orient, orient ); EXCHG( m_Orient, orient );
bool hit = TextHitTest(aPosRef); bool hit = TextHitTest( aPosRef );
EXCHG( m_Orient, orient ); EXCHG( m_Orient, orient );
m_Pos = tmp; m_Pos = tmp;
return hit; return hit;
...@@ -250,14 +250,14 @@ void LIB_TEXT::DoMirrorHorizontal( const wxPoint& center ) ...@@ -250,14 +250,14 @@ void LIB_TEXT::DoMirrorHorizontal( const wxPoint& center )
void LIB_TEXT::DoPlot( PLOTTER* plotter, const wxPoint& offset, bool fill, void LIB_TEXT::DoPlot( PLOTTER* plotter, const wxPoint& offset, bool fill,
const int transform[2][2] ) const TRANSFORM& aTransform )
{ {
wxASSERT( plotter != NULL ); wxASSERT( plotter != NULL );
/* The text orientation may need to be flipped if the /* The text orientation may need to be flipped if the
* transformation matrix causes xy axes to be flipped. */ * transformation matrix causes xy axes to be flipped. */
int t1 = ( transform[0][0] != 0 ) ^ ( m_Orient != 0 ); int t1 = ( aTransform.x1 != 0 ) ^ ( m_Orient != 0 );
wxPoint pos = TransformCoordinate( transform, m_Pos ) + offset; wxPoint pos = aTransform.TransformCoordinate( m_Pos ) + offset;
plotter->text( pos, UNSPECIFIED_COLOR, m_Text, plotter->text( pos, UNSPECIFIED_COLOR, m_Text,
t1 ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT, t1 ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT,
...@@ -285,13 +285,13 @@ int LIB_TEXT::GetPenSize( ) ...@@ -285,13 +285,13 @@ int LIB_TEXT::GetPenSize( )
return pensize; return pensize;
} }
void LIB_TEXT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
const wxPoint& aOffset, int aColor, int aDrawMode, void LIB_TEXT::drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOffset,
void* aData, const int aTransformMatrix[2][2] ) int aColor, int aDrawMode, void* aData, const TRANSFORM& aTransform )
{ {
wxPoint pos1, pos2; wxPoint pos1, pos2;
int color = ReturnLayerColor( LAYER_DEVICE ); int color = GetDefaultColor();
if( aColor < 0 ) // Used normal color or selected color if( aColor < 0 ) // Used normal color or selected color
{ {
...@@ -301,7 +301,7 @@ void LIB_TEXT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, ...@@ -301,7 +301,7 @@ void LIB_TEXT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
else else
color = aColor; color = aColor;
pos1 = TransformCoordinate( aTransformMatrix, m_Pos ) + aOffset; pos1 = aTransform.TransformCoordinate( m_Pos ) + aOffset;
GRSetDrawMode( aDC, aDrawMode ); GRSetDrawMode( aDC, aDrawMode );
...@@ -309,7 +309,7 @@ void LIB_TEXT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, ...@@ -309,7 +309,7 @@ void LIB_TEXT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
* orientation/mirror (needed when draw text in schematic) * orientation/mirror (needed when draw text in schematic)
*/ */
int orient = m_Orient; int orient = m_Orient;
if( aTransformMatrix[0][1] ) // Rotate component 90 degrees. if( aTransform.y1 ) // Rotate component 90 degrees.
{ {
if( orient == TEXT_ORIENT_HORIZ ) if( orient == TEXT_ORIENT_HORIZ )
orient = TEXT_ORIENT_VERT; orient = TEXT_ORIENT_VERT;
...@@ -329,27 +329,28 @@ void LIB_TEXT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, ...@@ -329,27 +329,28 @@ void LIB_TEXT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
* and use GetBoundaryBox to know the text coordinate considered as centered * and use GetBoundaryBox to know the text coordinate considered as centered
*/ */
EDA_Rect bBox = GetBoundingBox(); EDA_Rect bBox = GetBoundingBox();
pos1 = bBox.Centre(); // this is the coordinates of the graphic text relative to the component position pos1 = bBox.Centre(); // this is the coordinates of the graphic text relative to the
// in schematic Y axis orientation // component position in schematic Y axis orientation.
/* convert y coordinate from schematic to library Y axis orientation /* convert y coordinate from schematic to library Y axis orientation
* because we want to call TransformCoordinate to calculate real coordinates * because we want to call TransformCoordinate to calculate real coordinates
*/ */
NEGATE( pos1.y ); NEGATE( pos1.y );
pos1 = TransformCoordinate( aTransformMatrix, pos1 ) + aOffset; pos1 = aTransform.TransformCoordinate( pos1 ) + aOffset;
DrawGraphicText( aPanel, aDC, pos1, (EDA_Colors) color, m_Text, DrawGraphicText( aPanel, aDC, pos1, (EDA_Colors) color, m_Text, orient, m_Size,
orient, m_Size, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, GetPenSize(),
GetPenSize( ), m_Italic, m_Bold ); m_Italic, m_Bold );
/* Enable this to draw the bounding box around the text field to validate /* Enable this to draw the bounding box around the text field to validate
* the bounding box calculations. * the bounding box calculations.
*/ */
#if 0 #if 0
EDA_Rect grBox; EDA_Rect grBox;
bBox.SetY( -bBox.GetY() ); bBox.SetY( -bBox.GetY() );
bBox.SetHeight( -bBox.GetHeight()); bBox.SetHeight( -bBox.GetHeight());
grBox.SetOrigin( TransformCoordinate( aTransformMatrix, bBox.GetOrigin() ) ); grBox.SetOrigin( aTransform.TransformCoordinate( bBox.GetOrigin() ) );
grBox.SetEnd( TransformCoordinate( aTransformMatrix, bBox.GetEnd() ) ); grBox.SetEnd( aTransform.TransformCoordinate( bBox.GetEnd() ) );
grBox.Move( aOffset ); grBox.Move( aOffset );
GRRect( &aPanel->m_ClipBox, aDC, grBox.GetOrigin().x, grBox.GetOrigin().y, GRRect( &aPanel->m_ClipBox, aDC, grBox.GetOrigin().x, grBox.GetOrigin().y,
grBox.GetEnd().x, grBox.GetEnd().y, 0, LIGHTMAGENTA ); grBox.GetEnd().x, grBox.GetEnd().y, 0, LIGHTMAGENTA );
...@@ -357,14 +358,27 @@ void LIB_TEXT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, ...@@ -357,14 +358,27 @@ void LIB_TEXT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
} }
void LIB_TEXT::saveAttributes()
{
m_savedPos = m_Pos;
m_savedOrientation = m_Orient;
}
void LIB_TEXT::restoreAttributes()
{
m_Pos = m_savedPos;
m_Orient = m_savedOrientation;
}
void LIB_TEXT::DisplayInfo( WinEDA_DrawFrame* frame ) void LIB_TEXT::DisplayInfo( WinEDA_DrawFrame* frame )
{ {
wxString msg; wxString msg;
LIB_DRAW_ITEM::DisplayInfo( frame ); LIB_DRAW_ITEM::DisplayInfo( frame );
msg = ReturnStringFromValue( g_UserUnit, m_Width, msg = ReturnStringFromValue( g_UserUnit, m_Width, EESCHEMA_INTERNAL_UNIT, true );
EESCHEMA_INTERNAL_UNIT, true );
frame->AppendMsgPanel( _( "Line width" ), msg, BLUE ); frame->AppendMsgPanel( _( "Line width" ), msg, BLUE );
} }
...@@ -394,3 +408,79 @@ EDA_Rect LIB_TEXT::GetBoundingBox() ...@@ -394,3 +408,79 @@ EDA_Rect LIB_TEXT::GetBoundingBox()
rect.Normalize(); rect.Normalize();
return rect; return rect;
} }
void LIB_TEXT::Rotate()
{
if( InEditMode() )
{
m_rotate = true;
}
else
{
m_Orient = ( m_Orient == TEXT_ORIENT_VERT ) ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT;
}
}
void LIB_TEXT::BeginEdit( int aEditMode, const wxPoint aPosition )
{
wxCHECK_RET( ( aEditMode & ( IS_NEW | IS_MOVED ) ) != 0,
wxT( "Invalid edit mode for LIB_TEXT object." ) );
if( aEditMode == IS_MOVED )
{
m_initialPos = m_Pos;
m_initialCursorPos = aPosition;
saveAttributes();
SetEraseLastDrawItem();
}
else
{
m_Pos = aPosition;
}
m_Flags = aEditMode;
}
bool LIB_TEXT::ContinueEdit( const wxPoint aPosition )
{
wxCHECK_MSG( ( m_Flags & ( IS_NEW | IS_MOVED ) ) != 0, false,
wxT( "Bad call to ContinueEdit(). Text is not being edited." ) );
return false;
}
void LIB_TEXT::EndEdit( const wxPoint& aPosition, bool aAbort )
{
wxCHECK_RET( ( m_Flags & ( IS_NEW | IS_MOVED ) ) != 0,
wxT( "Bad call to EndEdit(). Text is not being edited." ) );
if( aAbort && !IsNew() )
restoreAttributes();
m_Flags = 0;
SetEraseLastDrawItem( false );
}
void LIB_TEXT::calcEdit( const wxPoint& aPosition )
{
if( m_rotate )
{
m_Orient = ( m_Orient == TEXT_ORIENT_VERT ) ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT;
m_rotate = false;
}
if( m_Flags == IS_NEW )
{
SetEraseLastDrawItem();
m_Pos = aPosition;
}
else if( m_Flags == IS_MOVED )
{
Move( m_initialPos + aPosition - m_initialCursorPos );
}
}
...@@ -30,17 +30,8 @@ void WinEDA_LibeditFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos ) ...@@ -30,17 +30,8 @@ void WinEDA_LibeditFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
{ {
if( DrawEntry && DrawEntry->m_Flags ) if( DrawEntry && DrawEntry->m_Flags )
{ {
// Don't put copy in undo list while resizing (because it's already done)
if (!(DrawEntry->m_Flags & IS_RESIZED))
SaveCopyInUndoList( m_component );
switch( DrawEntry->Type() ) switch( DrawEntry->Type() )
{ {
case COMPONENT_FIELD_DRAW_TYPE:
PlaceField( DC, (LIB_FIELD*) DrawEntry );
DrawEntry = NULL;
break;
case COMPONENT_PIN_DRAW_TYPE: case COMPONENT_PIN_DRAW_TYPE:
PlacePin( DC ); PlacePin( DC );
DrawEntry = NULL; DrawEntry = NULL;
...@@ -53,16 +44,13 @@ void WinEDA_LibeditFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos ) ...@@ -53,16 +44,13 @@ void WinEDA_LibeditFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
} }
else else
{ {
DrawEntry = DrawEntry = m_component->LocateDrawItem( m_unit, m_convert, TYPE_NOT_INIT,
m_component->LocateDrawItem( m_unit, m_convert, TYPE_NOT_INIT, GetScreen()->m_MousePosition );
GetScreen()->m_MousePosition );
if( DrawEntry == NULL ) if( DrawEntry == NULL )
{ {
DrawEntry = DrawEntry = m_component->LocateDrawItem( m_unit, m_convert, TYPE_NOT_INIT,
m_component->LocateDrawItem( m_unit, m_convert, GetScreen()->m_Curseur );
TYPE_NOT_INIT,
GetScreen()->m_Curseur );
} }
if( DrawEntry ) if( DrawEntry )
...@@ -106,35 +94,32 @@ void WinEDA_LibeditFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos ) ...@@ -106,35 +94,32 @@ void WinEDA_LibeditFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
if( m_drawItem->m_Flags & IS_NEW ) if( m_drawItem->m_Flags & IS_NEW )
GraphicItemBeginDraw( DC ); GraphicItemBeginDraw( DC );
else else
{
SaveCopyInUndoList( m_component );
EndDrawGraphicItem( DC ); EndDrawGraphicItem( DC );
}
} }
break; break;
case ID_LIBEDIT_DELETE_ITEM_BUTT: case ID_LIBEDIT_DELETE_ITEM_BUTT:
DrawEntry = DrawEntry = m_component->LocateDrawItem( m_unit, m_convert, TYPE_NOT_INIT,
m_component->LocateDrawItem( m_unit, m_convert, TYPE_NOT_INIT, GetScreen()->m_MousePosition );
GetScreen()->m_MousePosition );
if( DrawEntry == NULL ) if( DrawEntry == NULL )
{ {
DrawEntry = DrawEntry = m_component->LocateDrawItem( m_unit, m_convert, TYPE_NOT_INIT,
m_component->LocateDrawItem( m_unit, m_convert, GetScreen()->m_Curseur );
TYPE_NOT_INIT,
GetScreen()->m_Curseur );
} }
if( DrawEntry == NULL ) if( DrawEntry == NULL )
{ {
DisplayCmpDoc(); DisplayCmpDoc();
break; break;
} }
SaveCopyInUndoList( m_component ); SaveCopyInUndoList( m_component );
if( DrawEntry->Type() == COMPONENT_PIN_DRAW_TYPE ) if( DrawEntry->Type() == COMPONENT_PIN_DRAW_TYPE )
DeletePin( DC, m_component, (LIB_PIN*) DrawEntry ); DeletePin( DC, m_component, (LIB_PIN*) DrawEntry );
else else
m_component->RemoveDrawItem( DrawEntry, DrawPanel, DC ); m_component->RemoveDrawItem( DrawEntry, DrawPanel, DC );
DrawEntry = NULL; DrawEntry = NULL;
OnModify( ); OnModify( );
break; break;
...@@ -145,10 +130,8 @@ void WinEDA_LibeditFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos ) ...@@ -145,10 +130,8 @@ void WinEDA_LibeditFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
SetToolID( 0, wxCURSOR_ARROW, wxEmptyString ); SetToolID( 0, wxCURSOR_ARROW, wxEmptyString );
break; break;
default: default:
DisplayError( this, DisplayError( this, wxT( "WinEDA_LibeditFrame::OnLeftClick error" ) );
wxT( "WinEDA_LibeditFrame::OnLeftClick error" ) );
SetToolID( 0, wxCURSOR_ARROW, wxEmptyString ); SetToolID( 0, wxCURSOR_ARROW, wxEmptyString );
break; break;
} }
...@@ -163,7 +146,7 @@ void WinEDA_LibeditFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos ) ...@@ -163,7 +146,7 @@ void WinEDA_LibeditFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
*/ */
void WinEDA_LibeditFrame::OnLeftDClick( wxDC* DC, const wxPoint& MousePos ) void WinEDA_LibeditFrame::OnLeftDClick( wxDC* DC, const wxPoint& MousePos )
{ {
wxPoint pos = GetPosition(); wxPoint pos = GetPosition();
if( m_component == NULL ) if( m_component == NULL )
return; return;
...@@ -175,9 +158,8 @@ void WinEDA_LibeditFrame::OnLeftDClick( wxDC* DC, const wxPoint& MousePos ) ...@@ -175,9 +158,8 @@ void WinEDA_LibeditFrame::OnLeftDClick( wxDC* DC, const wxPoint& MousePos )
GetScreen()->m_MousePosition ); GetScreen()->m_MousePosition );
if( m_drawItem == NULL ) if( m_drawItem == NULL )
{ {
m_drawItem = m_drawItem = m_component->LocateDrawItem( m_unit, m_convert, TYPE_NOT_INIT,
m_component->LocateDrawItem( m_unit, m_convert, TYPE_NOT_INIT, GetScreen()->m_Curseur );
GetScreen()->m_Curseur );
} }
if( m_drawItem == NULL ) if( m_drawItem == NULL )
{ {
...@@ -241,8 +223,7 @@ void WinEDA_LibeditFrame::OnLeftDClick( wxDC* DC, const wxPoint& MousePos ) ...@@ -241,8 +223,7 @@ void WinEDA_LibeditFrame::OnLeftDClick( wxDC* DC, const wxPoint& MousePos )
default: default:
wxString msg; wxString msg;
msg.Printf( wxT( "WinEDA_LibeditFrame::OnLeftDClick Error: unknown \ msg.Printf( wxT( "WinEDA_LibeditFrame::OnLeftDClick Error: unknown StructType %d" ),
StructType %d" ),
m_drawItem->Type() ); m_drawItem->Type() );
DisplayError( this, msg ); DisplayError( this, msg );
break; break;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "confirm.h" #include "confirm.h"
#include "eda_doc.h" #include "eda_doc.h"
#include "bitmaps.h" #include "bitmaps.h"
#include "gr_basic.h"
#include "program.h" #include "program.h"
#include "general.h" #include "general.h"
...@@ -18,6 +19,7 @@ ...@@ -18,6 +19,7 @@
#include "eeschema_id.h" #include "eeschema_id.h"
#include "libeditframe.h" #include "libeditframe.h"
#include "class_library.h" #include "class_library.h"
#include "lib_polyline.h"
#include "kicad_device_context.h" #include "kicad_device_context.h"
#include "hotkeys.h" #include "hotkeys.h"
...@@ -163,6 +165,7 @@ WinEDA_LibeditFrame::WinEDA_LibeditFrame( WinEDA_SchematicFrame* aParent, ...@@ -163,6 +165,7 @@ WinEDA_LibeditFrame::WinEDA_LibeditFrame( WinEDA_SchematicFrame* aParent,
SetShowDeMorgan( false ); SetShowDeMorgan( false );
m_drawSpecificConvert = true; m_drawSpecificConvert = true;
m_drawSpecificUnit = false; m_drawSpecificUnit = false;
m_savedComponent = NULL;
m_HotkeysZoomAndGridList = s_Libedit_Hokeys_Descr; m_HotkeysZoomAndGridList = s_Libedit_Hokeys_Descr;
// Give an icon // Give an icon
...@@ -743,13 +746,20 @@ void WinEDA_LibeditFrame::Process_Special_Functions( wxCommandEvent& event ) ...@@ -743,13 +746,20 @@ void WinEDA_LibeditFrame::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_LIBEDIT_DELETE_CURRENT_POLY_SEGMENT: case ID_POPUP_LIBEDIT_DELETE_CURRENT_POLY_SEGMENT:
{
// Delete the last created segment, while creating a polyline draw item // Delete the last created segment, while creating a polyline draw item
if( m_drawItem == NULL ) if( m_drawItem == NULL )
break; break;
DrawPanel->MouseToCursorSchema(); DrawPanel->MouseToCursorSchema();
DeleteDrawPoly( &dc ); int oldFlags = m_drawItem->GetFlags();
m_drawItem->SetFlags( 0 );
m_drawItem->Draw( DrawPanel, &dc, wxPoint( 0, 0 ), -1, g_XorMode, NULL, DefaultTransform );
( (LIB_POLYLINE*) m_drawItem )->DeleteSegment( GetScreen()->GetCursorDrawPosition() );
m_drawItem->Draw( DrawPanel, &dc, wxPoint( 0, 0 ), -1, g_XorMode, NULL, DefaultTransform );
m_drawItem->SetFlags( oldFlags );
break; break;
}
case ID_POPUP_LIBEDIT_DELETE_ITEM: case ID_POPUP_LIBEDIT_DELETE_ITEM:
if( m_drawItem == NULL ) if( m_drawItem == NULL )
...@@ -780,8 +790,6 @@ void WinEDA_LibeditFrame::Process_Special_Functions( wxCommandEvent& event ) ...@@ -780,8 +790,6 @@ void WinEDA_LibeditFrame::Process_Special_Functions( wxCommandEvent& event )
DrawPanel->MouseToCursorSchema(); DrawPanel->MouseToCursorSchema();
if( m_drawItem->Type() == COMPONENT_PIN_DRAW_TYPE ) if( m_drawItem->Type() == COMPONENT_PIN_DRAW_TYPE )
StartMovePin( &dc ); StartMovePin( &dc );
else if( m_drawItem->Type() == COMPONENT_FIELD_DRAW_TYPE )
StartMoveField( &dc, (LIB_FIELD*) m_drawItem );
else else
StartMoveDrawSymbol( &dc ); StartMoveDrawSymbol( &dc );
break; break;
...@@ -798,35 +806,63 @@ void WinEDA_LibeditFrame::Process_Special_Functions( wxCommandEvent& event ) ...@@ -798,35 +806,63 @@ void WinEDA_LibeditFrame::Process_Special_Functions( wxCommandEvent& event )
|| m_drawItem->Type() == COMPONENT_ARC_DRAW_TYPE || m_drawItem->Type() == COMPONENT_ARC_DRAW_TYPE
) )
{ {
SaveCopyInUndoList( m_component );
StartModifyDrawSymbol( &dc ); StartModifyDrawSymbol( &dc );
} }
break; break;
case ID_POPUP_LIBEDIT_ROTATE_GRAPHIC_TEXT: case ID_POPUP_LIBEDIT_ROTATE_GRAPHIC_TEXT:
if( m_drawItem == NULL ) if( m_drawItem == NULL && m_drawItem->Type() != COMPONENT_GRAPHIC_TEXT_DRAW_TYPE )
break; break;
DrawPanel->CursorOff( &dc ); DrawPanel->CursorOff( &dc );
DrawPanel->MouseToCursorSchema(); DrawPanel->MouseToCursorSchema();
if( (m_drawItem->m_Flags & IS_NEW) == 0 ) if( !m_drawItem->InEditMode() )
{
SaveCopyInUndoList( m_component ); SaveCopyInUndoList( m_component );
RotateSymbolText( &dc ); m_drawItem->SetUnit( m_unit );
m_drawItem->Draw( DrawPanel, &dc, wxPoint( 0, 0 ), -1, g_XorMode, NULL,
DefaultTransform );
}
m_drawItem->Rotate();
if( !m_drawItem->InEditMode() )
{
m_drawItem->Draw( DrawPanel, &dc, wxPoint( 0, 0 ), -1, g_XorMode, NULL,
DefaultTransform );
DrawPanel->Refresh();
}
DrawPanel->CursorOn( &dc ); DrawPanel->CursorOn( &dc );
break; break;
case ID_POPUP_LIBEDIT_FIELD_ROTATE_ITEM: case ID_POPUP_LIBEDIT_FIELD_ROTATE_ITEM:
if( m_drawItem == NULL ) {
if( m_drawItem == NULL || ( m_drawItem->Type() != COMPONENT_FIELD_DRAW_TYPE ) )
break; break;
DrawPanel->CursorOff( &dc ); DrawPanel->CursorOff( &dc );
DrawPanel->MouseToCursorSchema(); DrawPanel->MouseToCursorSchema();
if( m_drawItem->Type() == COMPONENT_FIELD_DRAW_TYPE )
if( !m_drawItem->InEditMode() )
{ {
SaveCopyInUndoList( m_component ); SaveCopyInUndoList( m_component );
RotateField( &dc, (LIB_FIELD*) m_drawItem ); m_drawItem->SetUnit( m_unit );
m_drawItem->Draw( DrawPanel, &dc, wxPoint( 0, 0 ), -1, g_XorMode, NULL,
DefaultTransform );
}
m_drawItem->Rotate();
if( !m_drawItem->InEditMode() )
{
m_drawItem->Draw( DrawPanel, &dc, wxPoint( 0, 0 ), -1, g_XorMode, NULL,
DefaultTransform );
DrawPanel->Refresh();
} }
DrawPanel->CursorOn( &dc ); DrawPanel->CursorOn( &dc );
break; break;
}
case ID_POPUP_LIBEDIT_FIELD_EDIT_ITEM: case ID_POPUP_LIBEDIT_FIELD_EDIT_ITEM:
if( m_drawItem == NULL ) if( m_drawItem == NULL )
...@@ -925,9 +961,20 @@ void WinEDA_LibeditFrame::EnsureActiveLibExists() ...@@ -925,9 +961,20 @@ void WinEDA_LibeditFrame::EnsureActiveLibExists()
m_library = NULL; m_library = NULL;
} }
void WinEDA_LibeditFrame::SetLanguage( wxCommandEvent& event ) void WinEDA_LibeditFrame::SetLanguage( wxCommandEvent& event )
{ {
WinEDA_BasicFrame::SetLanguage( event ); WinEDA_BasicFrame::SetLanguage( event );
WinEDA_SchematicFrame *parent = (WinEDA_SchematicFrame *)GetParent(); WinEDA_SchematicFrame *parent = (WinEDA_SchematicFrame *)GetParent();
parent->WinEDA_BasicFrame::SetLanguage( event ); parent->WinEDA_BasicFrame::SetLanguage( event );
} }
void WinEDA_LibeditFrame::DeleteSavedComponent()
{
if( m_savedComponent )
{
delete m_savedComponent;
m_savedComponent = NULL;
}
}
...@@ -22,6 +22,8 @@ class Dialog_BodyGraphicText_Properties; ...@@ -22,6 +22,8 @@ class Dialog_BodyGraphicText_Properties;
*/ */
class WinEDA_LibeditFrame : public WinEDA_DrawFrame class WinEDA_LibeditFrame : public WinEDA_DrawFrame
{ {
LIB_COMPONENT* m_savedComponent; ///< Temporary copy of current component during edit.
public: public:
WinEDAChoiceBox* m_SelpartBox; // a Box to select a part to edit (if any) WinEDAChoiceBox* m_SelpartBox; // a Box to select a part to edit (if any)
WinEDAChoiceBox* m_SelAliasBox; // a box to select the alias to edit (if any) WinEDAChoiceBox* m_SelAliasBox; // a box to select the alias to edit (if any)
...@@ -94,11 +96,9 @@ public: ...@@ -94,11 +96,9 @@ public:
void OnLeftDClick( wxDC* DC, const wxPoint& MousePos ); void OnLeftDClick( wxDC* DC, const wxPoint& MousePos );
SCH_SCREEN* GetScreen() { return (SCH_SCREEN*) GetBaseScreen(); } SCH_SCREEN* GetScreen() { return (SCH_SCREEN*) GetBaseScreen(); }
void OnHotKey( wxDC* DC, int hotkey, void OnHotKey( wxDC* DC, int hotkey, EDA_BaseStruct* DrawStruct );
EDA_BaseStruct* DrawStruct );
void GeneralControle( wxDC* DC, void GeneralControle( wxDC* DC, wxPoint MousePositionInPixels );
wxPoint MousePositionInPixels );
void LoadSettings(); void LoadSettings();
void SaveSettings(); void SaveSettings();
...@@ -167,6 +167,8 @@ public: ...@@ -167,6 +167,8 @@ public:
FILL_T GetFillStyle( void ) { return m_drawFillStyle; } FILL_T GetFillStyle( void ) { return m_drawFillStyle; }
void DeleteSavedComponent();
private: private:
/** /**
...@@ -182,16 +184,14 @@ private: ...@@ -182,16 +184,14 @@ private:
void SelectActiveLibrary(); void SelectActiveLibrary();
void SaveActiveLibrary( wxCommandEvent& event ); void SaveActiveLibrary( wxCommandEvent& event );
bool LoadOneLibraryPartAux( CMP_LIB_ENTRY* LibEntry, bool LoadOneLibraryPartAux( CMP_LIB_ENTRY* LibEntry, CMP_LIBRARY* Library );
CMP_LIBRARY* Library );
void DisplayCmpDoc(); void DisplayCmpDoc();
void EditComponentProperties(); void EditComponentProperties();
// General editing // General editing
public: public:
void SaveCopyInUndoList( EDA_BaseStruct* ItemToCopy, void SaveCopyInUndoList( EDA_BaseStruct* ItemToCopy, int flag_type_command = 0 );
int flag_type_command = 0 );
private: private:
void GetComponentFromUndoList( wxCommandEvent& event ); void GetComponentFromUndoList( wxCommandEvent& event );
...@@ -199,9 +199,7 @@ private: ...@@ -199,9 +199,7 @@ private:
// Editing pins // Editing pins
void CreatePin( wxDC* DC ); void CreatePin( wxDC* DC );
void DeletePin( wxDC* DC, void DeletePin( wxDC* DC, LIB_COMPONENT* LibEntry, LIB_PIN* Pin );
LIB_COMPONENT* LibEntry,
LIB_PIN* Pin );
void StartMovePin( wxDC* DC ); void StartMovePin( wxDC* DC );
// Editing anchor // Editing anchor
...@@ -215,16 +213,10 @@ private: ...@@ -215,16 +213,10 @@ private:
void EndDrawGraphicItem( wxDC* DC ); void EndDrawGraphicItem( wxDC* DC );
void LoadOneSymbol(); void LoadOneSymbol();
void SaveOneSymbol(); void SaveOneSymbol();
void EditGraphicSymbol( wxDC* DC, void EditGraphicSymbol( wxDC* DC, LIB_DRAW_ITEM* DrawItem );
LIB_DRAW_ITEM* DrawItem );
void EditSymbolText( wxDC* DC, LIB_DRAW_ITEM* DrawItem ); void EditSymbolText( wxDC* DC, LIB_DRAW_ITEM* DrawItem );
void RotateSymbolText( wxDC* DC );
void DeleteDrawPoly( wxDC* DC );
LIB_DRAW_ITEM* LocateItemUsingCursor(); LIB_DRAW_ITEM* LocateItemUsingCursor();
void RotateField( wxDC* DC, LIB_FIELD* Field );
void PlaceField( wxDC* DC, LIB_FIELD* Field );
void EditField( wxDC* DC, LIB_FIELD* Field ); void EditField( wxDC* DC, LIB_FIELD* Field );
void StartMoveField( wxDC* DC, LIB_FIELD* field );
public: public:
/* Block commands: */ /* Block commands: */
...@@ -311,9 +303,8 @@ protected: ...@@ -311,9 +303,8 @@ protected:
* @param aPrintMirrorMode = not used here (Set when printing in mirror mode) * @param aPrintMirrorMode = not used here (Set when printing in mirror mode)
* @param aData = a pointer on an auxiliary data (not always used, NULL if not used) * @param aData = a pointer on an auxiliary data (not always used, NULL if not used)
*/ */
virtual void PrintPage( wxDC* aDC, bool aPrint_Sheet_Ref, virtual void PrintPage( wxDC* aDC, bool aPrint_Sheet_Ref, int aPrintMask,
int aPrintMask, bool aPrintMirrorMode, bool aPrintMirrorMode, void * aData = NULL);
void * aData = NULL);
/** function SVG_Print_component /** function SVG_Print_component
* Creates the SVG print file for the current edited component. * Creates the SVG print file for the current edited component.
......
...@@ -15,120 +15,7 @@ ...@@ -15,120 +15,7 @@
#include "class_library.h" #include "class_library.h"
static void ShowMoveField( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
extern int m_unit; extern int m_unit;
static wxPoint s_InitialPosition, s_LastPosition;
static void AbortMoveField( WinEDA_DrawPanel* Panel, wxDC* DC )
{
Panel->ManageCurseur = NULL;
Panel->ForceCloseManageCurseur = NULL;
WinEDA_LibeditFrame* parent = (WinEDA_LibeditFrame*) Panel->GetParent();
if( parent == NULL )
return;
LIB_DRAW_ITEM* item = parent->GetDrawItem();
if( item == NULL )
return;
wxPoint curpos = Panel->GetScreen()->m_Curseur;
Panel->GetScreen()->m_Curseur = s_InitialPosition;
ShowMoveField( Panel, DC, true );
Panel->GetScreen()->m_Curseur = curpos;
item->m_Flags = 0;
parent->SetDrawItem( NULL );
}
void WinEDA_LibeditFrame::StartMoveField( wxDC* DC, LIB_FIELD* field )
{
wxPoint startPos;
if( ( m_component == NULL ) || ( field == NULL ) )
return;
m_drawItem = field;
s_InitialPosition = field->m_Pos;
NEGATE( s_InitialPosition.y );
m_drawItem->m_Flags |= IS_MOVED;
DrawPanel->CursorOff( DC );
s_LastPosition = s_InitialPosition;
GetScreen()->m_Curseur = s_InitialPosition;
DrawPanel->MouseToCursorSchema();
DrawPanel->ManageCurseur = ShowMoveField;
DrawPanel->ForceCloseManageCurseur = AbortMoveField;
DrawPanel->ManageCurseur( DrawPanel, DC, true );
s_InitialPosition = GetScreen()->m_Curseur;
DrawPanel->CursorOn( DC );
}
/*
* Routine to display text 'Field' on the move.
* Normally called by cursor management code.
*/
static void ShowMoveField( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
{
WinEDA_LibeditFrame* parent = (WinEDA_LibeditFrame*) panel->GetParent();
if( parent == NULL )
return;
LIB_FIELD* Field = (LIB_FIELD*) parent->GetDrawItem();
if( Field == NULL )
return;
wxString text = Field->GetFullText( parent->GetUnit() );
wxPoint offset;
offset.x = s_LastPosition.x - Field->m_Pos.x;
offset.y = s_LastPosition.y + Field->m_Pos.y;
if( erase )
Field->Draw( panel, DC, offset, -1, g_XorMode, &text,
DefaultTransformMatrix );
s_LastPosition = panel->GetScreen()->m_Curseur;
offset.x = s_LastPosition.x - Field->m_Pos.x;
offset.y = s_LastPosition.y + Field->m_Pos.y;
Field->Draw( panel, DC, offset, -1, g_XorMode, &text,
DefaultTransformMatrix );
}
void WinEDA_LibeditFrame::PlaceField( wxDC* DC, LIB_FIELD* Field )
{
if( Field == NULL )
return;
Field->m_Flags = 0;
Field->m_Pos.x = GetScreen()->m_Curseur.x;
Field->m_Pos.y = -GetScreen()->m_Curseur.y;
DrawPanel->CursorOff( DC );
wxString fieldText = Field->GetFullText( m_unit );
Field->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, GR_DEFAULT_DRAWMODE,
&fieldText, DefaultTransformMatrix );
DrawPanel->CursorOn( DC );
OnModify();
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
m_drawItem = NULL;
}
void WinEDA_LibeditFrame::EditField( wxDC* DC, LIB_FIELD* Field ) void WinEDA_LibeditFrame::EditField( wxDC* DC, LIB_FIELD* Field )
{ {
...@@ -202,12 +89,11 @@ names in the alias list." ), ...@@ -202,12 +89,11 @@ names in the alias list." ),
*/ */
if( m_library && m_library->FindEntry( Text ) != NULL ) if( m_library && m_library->FindEntry( Text ) != NULL )
{ {
msg.Printf( _( msg.Printf( _( "The field name <%s> conflicts with an existing \
"The field name <%s> conflicts with an existing \
entry in the component library <%s>.\nPlease choose another name that does \ entry in the component library <%s>.\nPlease choose another name that does \
not conflict with any library entries." ), not conflict with any library entries." ),
GetChars( Text ), GetChars( Text ),
GetChars( m_library->GetName() ) ); GetChars( m_library->GetName() ) );
DisplayError( this, msg ); DisplayError( this, msg );
return; return;
} }
...@@ -217,8 +103,8 @@ not conflict with any library entries." ...@@ -217,8 +103,8 @@ not conflict with any library entries."
Field->GetParent()->SetName( Text ); Field->GetParent()->SetName( Text );
} }
Field->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, g_XorMode, &fieldText, ( ( LIB_DRAW_ITEM* )Field )->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, g_XorMode,
DefaultTransformMatrix ); &fieldText, DefaultTransform );
if( !Text.IsEmpty() ) if( !Text.IsEmpty() )
{ {
...@@ -237,57 +123,14 @@ not conflict with any library entries." ...@@ -237,57 +123,14 @@ not conflict with any library entries."
if( Field->m_Flags == 0 ) if( Field->m_Flags == 0 )
drawMode = GR_DEFAULT_DRAWMODE; drawMode = GR_DEFAULT_DRAWMODE;
Field->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, drawMode, &fieldText, ( ( LIB_DRAW_ITEM* )Field )->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, drawMode,
DefaultTransformMatrix ); &fieldText, DefaultTransform );
OnModify(); OnModify();
UpdateAliasSelectList(); UpdateAliasSelectList();
} }
/*
* Rotate a field horizontally or vertically.
*
* If a field is being edited, rotate.
* Otherwise rotate the field at the current cursor position.
*/
void WinEDA_LibeditFrame::RotateField( wxDC* DC, LIB_FIELD* Field )
{
if( Field == NULL )
return;
OnModify();
DrawPanel->CursorOff( DC );
GRSetDrawMode( DC, g_XorMode );
wxString fieldText = Field->GetFullText( m_unit );
if( (Field->m_Flags & IS_MOVED) )
ShowMoveField( DrawPanel, DC, false );
else
Field->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, g_XorMode, &fieldText,
DefaultTransformMatrix );
if( Field->m_Orient == TEXT_ORIENT_VERT )
Field->m_Orient = TEXT_ORIENT_HORIZ;
else
Field->m_Orient = TEXT_ORIENT_VERT;
int drawMode = g_XorMode;
if( Field->m_Flags == 0 )
drawMode = GR_DEFAULT_DRAWMODE;
if( (Field->m_Flags & IS_MOVED) )
ShowMoveField( DrawPanel, DC, false );
else
Field->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, drawMode, &fieldText,
DefaultTransformMatrix );
DrawPanel->CursorOn( DC );
}
LIB_DRAW_ITEM* WinEDA_LibeditFrame::LocateItemUsingCursor() LIB_DRAW_ITEM* WinEDA_LibeditFrame::LocateItemUsingCursor()
{ {
if( m_component == NULL ) if( m_component == NULL )
...@@ -295,13 +138,11 @@ LIB_DRAW_ITEM* WinEDA_LibeditFrame::LocateItemUsingCursor() ...@@ -295,13 +138,11 @@ LIB_DRAW_ITEM* WinEDA_LibeditFrame::LocateItemUsingCursor()
if( ( m_drawItem == NULL ) || ( m_drawItem->m_Flags == 0 ) ) if( ( m_drawItem == NULL ) || ( m_drawItem->m_Flags == 0 ) )
{ {
m_drawItem = m_component->LocateDrawItem( m_unit, m_convert, m_drawItem = m_component->LocateDrawItem( m_unit, m_convert, TYPE_NOT_INIT,
TYPE_NOT_INIT,
GetScreen()->m_MousePosition ); GetScreen()->m_MousePosition );
if( m_drawItem == NULL ) if( m_drawItem == NULL )
m_drawItem = m_component->LocateDrawItem( m_unit, m_convert, m_drawItem = m_component->LocateDrawItem( m_unit, m_convert, TYPE_NOT_INIT,
TYPE_NOT_INIT,
GetScreen()->m_Curseur ); GetScreen()->m_Curseur );
} }
......
...@@ -602,9 +602,8 @@ static void AddConnectedObjects( SCH_SHEET_PATH* sheetlist, ...@@ -602,9 +602,8 @@ static void AddConnectedObjects( SCH_SHEET_PATH* sheetlist,
( pin->m_Convert != DrawLibItem->m_Convert ) ) ( pin->m_Convert != DrawLibItem->m_Convert ) )
continue; continue;
wxPoint pos2 = wxPoint pos2 = DrawLibItem->m_Transform.TransformCoordinate( pin->m_Pos ) +
TransformCoordinate( DrawLibItem->m_Transform, DrawLibItem->m_Pos;
pin->m_Pos ) + DrawLibItem->m_Pos;
new_item = new NETLIST_OBJECT(); new_item = new NETLIST_OBJECT();
new_item->m_SheetListInclude = *sheetlist; new_item->m_SheetListInclude = *sheetlist;
......
...@@ -275,7 +275,7 @@ another pin. Continue?" ) ); ...@@ -275,7 +275,7 @@ another pin. Continue?" ) );
DrawPanel->CursorOff( DC ); DrawPanel->CursorOff( DC );
bool showPinText = true; bool showPinText = true;
CurrentPin->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, GR_DEFAULT_DRAWMODE, CurrentPin->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, GR_DEFAULT_DRAWMODE,
&showPinText, DefaultTransformMatrix ); &showPinText, DefaultTransform );
DrawPanel->CursorOn( DC ); DrawPanel->CursorOn( DC );
m_drawItem = NULL; m_drawItem = NULL;
...@@ -346,14 +346,13 @@ static void DrawMovePin( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ) ...@@ -346,14 +346,13 @@ static void DrawMovePin( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
{ {
CurrentPin->m_Pos = PinPreviousPos; CurrentPin->m_Pos = PinPreviousPos;
CurrentPin->Draw( panel, DC, wxPoint( 0, 0 ), -1, g_XorMode, CurrentPin->Draw( panel, DC, wxPoint( 0, 0 ), -1, g_XorMode,
&showPinText, DefaultTransformMatrix ); &showPinText, DefaultTransform );
} }
/* Redraw pin in new position */ /* Redraw pin in new position */
CurrentPin->m_Pos.x = panel->GetScreen()->m_Curseur.x; CurrentPin->m_Pos.x = panel->GetScreen()->m_Curseur.x;
CurrentPin->m_Pos.y = -panel->GetScreen()->m_Curseur.y; CurrentPin->m_Pos.y = -panel->GetScreen()->m_Curseur.y;
CurrentPin->Draw( panel, DC, wxPoint( 0, 0 ), -1, g_XorMode, CurrentPin->Draw( panel, DC, wxPoint( 0, 0 ), -1, g_XorMode, &showPinText, DefaultTransform );
&showPinText, DefaultTransformMatrix );
PinPreviousPos = CurrentPin->m_Pos; PinPreviousPos = CurrentPin->m_Pos;
...@@ -471,14 +470,13 @@ void WinEDA_LibeditFrame::CreatePin( wxDC* DC ) ...@@ -471,14 +470,13 @@ void WinEDA_LibeditFrame::CreatePin( wxDC* DC )
DrawPanel->ForceCloseManageCurseur = AbortPinMove; DrawPanel->ForceCloseManageCurseur = AbortPinMove;
if( DC ) if( DC )
pin->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, wxCOPY, &showPinText, pin->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, wxCOPY, &showPinText,
DefaultTransformMatrix ); DefaultTransform );
} }
} }
static void CreateImagePins( LIB_PIN* Pin, int unit, int convert, static void CreateImagePins( LIB_PIN* Pin, int unit, int convert, bool asDeMorgan )
bool asDeMorgan )
{ {
int ii; int ii;
LIB_PIN* NewPin; LIB_PIN* NewPin;
...@@ -556,8 +554,7 @@ void WinEDA_LibeditFrame::GlobalSetPins( wxDC* DC, LIB_PIN* MasterPin, int id ) ...@@ -556,8 +554,7 @@ void WinEDA_LibeditFrame::GlobalSetPins( wxDC* DC, LIB_PIN* MasterPin, int id )
if( selected && ( Pin->m_Selected & IS_SELECTED ) == 0 ) if( selected && ( Pin->m_Selected & IS_SELECTED ) == 0 )
continue; continue;
Pin->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, g_XorMode, Pin->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, g_XorMode, &showPinText, DefaultTransform );
&showPinText, DefaultTransformMatrix );
switch( id ) switch( id )
{ {
...@@ -574,8 +571,8 @@ void WinEDA_LibeditFrame::GlobalSetPins( wxDC* DC, LIB_PIN* MasterPin, int id ) ...@@ -574,8 +571,8 @@ void WinEDA_LibeditFrame::GlobalSetPins( wxDC* DC, LIB_PIN* MasterPin, int id )
break; break;
} }
Pin->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, GR_DEFAULT_DRAWMODE, ( ( LIB_DRAW_ITEM* )Pin )->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, GR_DEFAULT_DRAWMODE,
&showPinText, DefaultTransformMatrix ); &showPinText, DefaultTransform );
} }
} }
......
...@@ -40,18 +40,18 @@ static void PlotNoConnectStruct( PLOTTER* plotter, SCH_NO_CONNECT* Struct ) ...@@ -40,18 +40,18 @@ static void PlotNoConnectStruct( PLOTTER* plotter, SCH_NO_CONNECT* Struct )
static void PlotLibPart( PLOTTER* plotter, SCH_COMPONENT* DrawLibItem ) static void PlotLibPart( PLOTTER* plotter, SCH_COMPONENT* DrawLibItem )
{ {
LIB_COMPONENT* Entry; LIB_COMPONENT* Entry;
int TransMat[2][2]; TRANSFORM temp = TRANSFORM();
Entry = CMP_LIBRARY::FindLibraryComponent( DrawLibItem->m_ChipName ); Entry = CMP_LIBRARY::FindLibraryComponent( DrawLibItem->m_ChipName );
if( Entry == NULL ) if( Entry == NULL )
return;; return;;
memcpy( TransMat, DrawLibItem->m_Transform, sizeof(TransMat) ); temp = DrawLibItem->m_Transform;
Entry->Plot( plotter, DrawLibItem->m_Multi, DrawLibItem->m_Convert, Entry->Plot( plotter, DrawLibItem->m_Multi, DrawLibItem->m_Convert, DrawLibItem->m_Pos, temp );
DrawLibItem->m_Pos, TransMat );
bool isMulti = Entry->GetPartCount() > 1; bool isMulti = Entry->GetPartCount() > 1;
for( int fieldId = 0; fieldId < DrawLibItem->GetFieldCount(); fieldId++ ) for( int fieldId = 0; fieldId < DrawLibItem->GetFieldCount(); fieldId++ )
{ {
PlotTextField( plotter, DrawLibItem, fieldId, isMulti, 0 ); PlotTextField( plotter, DrawLibItem, fieldId, isMulti, 0 );
...@@ -85,7 +85,7 @@ static void PlotTextField( PLOTTER* plotter, SCH_COMPONENT* DrawLibItem, ...@@ -85,7 +85,7 @@ static void PlotTextField( PLOTTER* plotter, SCH_COMPONENT* DrawLibItem,
/* Calculate the text orientation, according to the component /* Calculate the text orientation, according to the component
* orientation/mirror */ * orientation/mirror */
int orient = field->m_Orient; int orient = field->m_Orient;
if( DrawLibItem->m_Transform[0][1] ) // Rotate component 90 deg. if( DrawLibItem->m_Transform.y1 ) // Rotate component 90 deg.
{ {
if( orient == TEXT_ORIENT_HORIZ ) if( orient == TEXT_ORIENT_HORIZ )
orient = TEXT_ORIENT_VERT; orient = TEXT_ORIENT_VERT;
......
...@@ -5,14 +5,18 @@ ...@@ -5,14 +5,18 @@
#ifndef PROGRAM_H #ifndef PROGRAM_H
#define PROGRAM_H #define PROGRAM_H
class TRANSFORM;
#define HIGHLIGHT_COLOR WHITE #define HIGHLIGHT_COLOR WHITE
#define TEXT_NO_VISIBLE 1 #define TEXT_NO_VISIBLE 1
#include "wxEeschemaStruct.h" #include "wxEeschemaStruct.h"
#include "macros.h" #include "macros.h"
#include "base_struct.h" #include "base_struct.h"
#include "sch_item_struct.h"
#include "sch_item_struct.h"
#include "class_sch_component.h" #include "class_sch_component.h"
#include "class_sch_screen.h" #include "class_sch_screen.h"
#include "class_drawsheet.h" #include "class_drawsheet.h"
...@@ -26,10 +30,8 @@ ...@@ -26,10 +30,8 @@
* a defualt matix ( no rotation, no mirror but Y axis is bottom to top, and * a defualt matix ( no rotation, no mirror but Y axis is bottom to top, and
* Y draw axis is to to bottom so we must have a default matix that reverses * Y draw axis is to to bottom so we must have a default matix that reverses
* the Y coordinate and keeps the X coordiate * the Y coordinate and keeps the X coordiate
* DefaultTransformMatrix[0][0] = 1; DefaultTransformMatrix[1][1] = -1;
* DefaultTransformMatrix[1][0] = DefaultTransformMatrix[0][1] = 0;
*/ */
extern int DefaultTransformMatrix[2][2]; extern TRANSFORM DefaultTransform;
#define MIN_BUSLINES_THICKNESS 12 // min bus lines and entries thickness #define MIN_BUSLINES_THICKNESS 12 // min bus lines and entries thickness
......
...@@ -50,19 +50,6 @@ void IncrementLabelMember( wxString& name ); ...@@ -50,19 +50,6 @@ void IncrementLabelMember( wxString& name );
/****************/ /****************/
void InstallCmpeditFrame( WinEDA_SchematicFrame* parent, wxPoint& pos, SCH_COMPONENT* m_Cmp ); void InstallCmpeditFrame( WinEDA_SchematicFrame* parent, wxPoint& pos, SCH_COMPONENT* m_Cmp );
bool MapAngles( int* Angle1, int* Angle2, const int TransMat[2][2] );
/**
* Calculate new coordinate according to the transform matrix.
*
* @param aTransformMatrix = rotation, mirror .. matrix
* @param aPosition = the position to transform
* @return the new coordinate
*/
wxPoint TransformCoordinate( const int aTransformMatrix[2][2], const wxPoint& aPosition );
void SnapLibItemPoint( int OrigX, void SnapLibItemPoint( int OrigX,
int OrigY, int OrigY,
int* ClosestX, int* ClosestX,
......
...@@ -809,14 +809,12 @@ int ReadPartDescr( wxWindow* frame, char* Line, FILE* f, wxString& aMsgDiag, ...@@ -809,14 +809,12 @@ int ReadPartDescr( wxWindow* frame, char* Line, FILE* f, wxString& aMsgDiag,
*aLineNum++; *aLineNum++;
if( ( fgets( Line, 256 - 1, f ) == NULL ) if( ( fgets( Line, 256 - 1, f ) == NULL )
|| ( sscanf( Line, "%d %d %d %d", || ( sscanf( Line, "%d %d %d %d",
&component->m_Transform[0][0], &component->m_Transform.x1,
&component->m_Transform[0][1], &component->m_Transform.y1,
&component->m_Transform[1][0], &component->m_Transform.x2,
&component->m_Transform[1][1] ) != 4 ) ) &component->m_Transform.y2 ) != 4 ) )
{ {
aMsgDiag.Printf( aMsgDiag.Printf( wxT( "Component orient error at line %d, aborted" ), *aLineNum );
wxT( "Component orient error at line %d, aborted" ),
*aLineNum );
Failed = TRUE; Failed = TRUE;
return Failed; return Failed;
} }
......
...@@ -6,16 +6,11 @@ ...@@ -6,16 +6,11 @@
#include "fctsys.h" #include "fctsys.h"
#include "gr_basic.h" #include "gr_basic.h"
#include "appl_wxstruct.h"
#include "common.h"
#include "class_drawpanel.h" #include "class_drawpanel.h"
#include "confirm.h" #include "confirm.h"
#include "eeschema_id.h"
#include "eeschema_id.h"
#include "program.h" #include "program.h"
#include "general.h"
#include "trigo.h"
#include "protos.h"
#include "libeditframe.h" #include "libeditframe.h"
#include "class_libentry.h" #include "class_libentry.h"
#include "dialog_lib_edit_draw_item.h" #include "dialog_lib_edit_draw_item.h"
...@@ -24,38 +19,10 @@ ...@@ -24,38 +19,10 @@
#include "lib_polyline.h" #include "lib_polyline.h"
#include "lib_rectangle.h" #include "lib_rectangle.h"
#include <boost/foreach.hpp>
static void SymbolDisplayDraw( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
static void ComputeArc( LIB_ARC* DrawItem, wxPoint ArcCentre );
static void ComputeArcRadiusAngles( LIB_ARC* arc );
static wxPoint ComputeCircumCenter( wxPoint A, wxPoint B, wxPoint C );
static void RedrawWhileMovingCursor( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
static wxPoint InitPosition, StartCursor, ItemPreviousPos;
typedef enum { static void SymbolDisplayDraw( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
START_POINT, END_POINT, OUTLINE static void RedrawWhileMovingCursor( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
} SelectedPoint;
// Attributes of the arc in edit
static struct
{
wxPoint startPoint, endPoint; //!< Start, end coordinates
int stateDrawArc; //!< The actual drawing state
double distanceCenter; //!< Distance from arc center to middle of start-/end-point
SelectedPoint selectedPoint; //!< The selected point while modifying
int direction; //!< Determines the side of the center point relative to start/end point
} arcState;
// Structure for saving attributes before modifying graphics objects
static struct
{
wxPoint startPoint;
wxPoint endPoint;
wxPoint centerPoint;
int radius;
} savedAttributes;
/* /*
* Show the dialog box for editing a graphical item properties * Show the dialog box for editing a graphical item properties
...@@ -65,7 +32,7 @@ void WinEDA_LibeditFrame::EditGraphicSymbol( wxDC* DC, LIB_DRAW_ITEM* DrawItem ) ...@@ -65,7 +32,7 @@ void WinEDA_LibeditFrame::EditGraphicSymbol( wxDC* DC, LIB_DRAW_ITEM* DrawItem )
if( DrawItem == NULL ) if( DrawItem == NULL )
return; return;
LIB_COMPONENT* component = DrawItem->GetParent(); LIB_COMPONENT* component = DrawItem->GetParent();
DIALOG_LIB_EDIT_DRAW_ITEM dialog( this, DrawItem->m_typeName ); DIALOG_LIB_EDIT_DRAW_ITEM dialog( this, DrawItem->m_typeName );
...@@ -129,75 +96,29 @@ void WinEDA_LibeditFrame::EditGraphicSymbol( wxDC* DC, LIB_DRAW_ITEM* DrawItem ) ...@@ -129,75 +96,29 @@ void WinEDA_LibeditFrame::EditGraphicSymbol( wxDC* DC, LIB_DRAW_ITEM* DrawItem )
static void AbortSymbolTraceOn( WinEDA_DrawPanel* Panel, wxDC* DC ) static void AbortSymbolTraceOn( WinEDA_DrawPanel* Panel, wxDC* DC )
{ {
LIB_DRAW_ITEM* item;
WinEDA_LibeditFrame* parent = (WinEDA_LibeditFrame*) Panel->GetParent(); WinEDA_LibeditFrame* parent = (WinEDA_LibeditFrame*) Panel->GetParent();
LIB_DRAW_ITEM* item = parent->GetDrawItem();
item = parent->GetDrawItem();
if( item == NULL ) if( item == NULL )
return; return;
arcState.stateDrawArc = 0;
Panel->ManageCurseur = NULL; Panel->ManageCurseur = NULL;
Panel->ForceCloseManageCurseur = NULL; Panel->ForceCloseManageCurseur = NULL;
if( item->m_Flags & IS_NEW ) bool deleteItem = item->IsNew();
item->EndEdit( parent->GetScreen()->GetCursorDrawPosition(), true );
// This draw is required to restore the item to it's last state.
item->Draw( Panel, DC, wxPoint( 0, 0 ), -1, g_XorMode, NULL, DefaultTransform );
if( deleteItem )
{ {
SAFE_DELETE( item ); SAFE_DELETE( item );
parent->SetDrawItem( NULL ); parent->SetDrawItem( NULL );
} }
else
{
// Restore old attributes, when the item was modified
if( item->m_Flags == IS_RESIZED )
{
item->Draw( Panel, DC, wxPoint( 0, 0 ), -1, g_XorMode, NULL, DefaultTransformMatrix );
switch( item->Type() )
{
case COMPONENT_CIRCLE_DRAW_TYPE:
( (LIB_CIRCLE*) item )->m_Radius = savedAttributes.radius;
break;
case COMPONENT_RECT_DRAW_TYPE:
( (LIB_RECTANGLE*) item )->m_Pos = savedAttributes.startPoint;
( (LIB_RECTANGLE*) item )->m_End = savedAttributes.endPoint;
break;
case COMPONENT_POLYLINE_DRAW_TYPE:
{
wxPoint point = savedAttributes.startPoint;
int index = ( (LIB_POLYLINE*) item )->m_ModifyIndex;
( ( (LIB_POLYLINE*) item )->m_PolyPoints )[index] = point;
}
break;
case COMPONENT_ARC_DRAW_TYPE:
( (LIB_ARC*) item )->m_ArcStart = savedAttributes.startPoint;
( (LIB_ARC*) item )->m_ArcEnd = savedAttributes.endPoint;
( (LIB_ARC*) item )->m_Pos = savedAttributes.centerPoint;
ComputeArcRadiusAngles( (LIB_ARC*) item );
break;
default:
break;
}
item->m_Flags = 0;
}
else
{
wxPoint curpos = Panel->GetScreen()->m_Curseur;
Panel->GetScreen()->m_Curseur = StartCursor;
RedrawWhileMovingCursor( Panel, DC, TRUE );
Panel->GetScreen()->m_Curseur = curpos;
}
item->m_Flags = 0;
}
Panel->Refresh( ); parent->DeleteSavedComponent();
Panel->Refresh();
} }
...@@ -205,69 +126,32 @@ LIB_DRAW_ITEM* WinEDA_LibeditFrame::CreateGraphicItem( LIB_COMPONENT* LibEntry, ...@@ -205,69 +126,32 @@ LIB_DRAW_ITEM* WinEDA_LibeditFrame::CreateGraphicItem( LIB_COMPONENT* LibEntry,
{ {
DrawPanel->ManageCurseur = SymbolDisplayDraw; DrawPanel->ManageCurseur = SymbolDisplayDraw;
DrawPanel->ForceCloseManageCurseur = AbortSymbolTraceOn; DrawPanel->ForceCloseManageCurseur = AbortSymbolTraceOn;
wxPoint drawPos = GetScreen()->GetCursorDrawPosition();
switch( m_ID_current_state ) switch( m_ID_current_state )
{ {
case ID_LIBEDIT_BODY_ARC_BUTT: case ID_LIBEDIT_BODY_ARC_BUTT:
{ {
LIB_ARC* Arc = new LIB_ARC( LibEntry ); m_drawItem = new LIB_ARC( LibEntry );
break;
m_drawItem = Arc;
arcState.startPoint.x = arcState.endPoint.x = GetScreen()->m_Curseur.x;
arcState.startPoint.y = arcState.endPoint.y = -( GetScreen()->m_Curseur.y );
arcState.stateDrawArc = 1;
Arc->m_Fill = m_drawFillStyle;
Arc->m_Width = m_drawLineWidth;
} }
break;
case ID_LIBEDIT_BODY_CIRCLE_BUTT: case ID_LIBEDIT_BODY_CIRCLE_BUTT:
{ m_drawItem = new LIB_CIRCLE( LibEntry );
LIB_CIRCLE* Circle = new LIB_CIRCLE( LibEntry ); break;
m_drawItem = Circle;
Circle->m_Pos = GetScreen()->m_Curseur;
NEGATE( Circle->m_Pos.y );
Circle->m_Fill = m_drawFillStyle;
Circle->m_Width = m_drawLineWidth;
}
break;
case ID_LIBEDIT_BODY_RECT_BUTT: case ID_LIBEDIT_BODY_RECT_BUTT:
{ m_drawItem = new LIB_RECTANGLE( LibEntry );
LIB_RECTANGLE* Square = new LIB_RECTANGLE( LibEntry ); break;
m_drawItem = Square;
Square->m_Pos = GetScreen()->m_Curseur;
NEGATE( Square->m_Pos.y );
Square->m_End = Square->m_Pos;
Square->m_Fill = m_drawFillStyle;
Square->m_Width = m_drawLineWidth;
}
break;
case ID_LIBEDIT_BODY_LINE_BUTT: case ID_LIBEDIT_BODY_LINE_BUTT:
{ m_drawItem = new LIB_POLYLINE( LibEntry );
LIB_POLYLINE* polyline = new LIB_POLYLINE( LibEntry ); break;
m_drawItem = polyline;
wxPoint point = GetScreen()->m_Curseur;
NEGATE( point.y );
polyline->AddPoint( point ); // Start point of the current segment
polyline->AddPoint( point ); // End point of the current segment
polyline->m_Fill = m_drawFillStyle;
polyline->m_Width = m_drawLineWidth;
}
break;
case ID_LIBEDIT_BODY_TEXT_BUTT: case ID_LIBEDIT_BODY_TEXT_BUTT:
{ {
LIB_TEXT* Text = new LIB_TEXT( LibEntry ); LIB_TEXT* Text = new LIB_TEXT( LibEntry );
m_drawItem = Text;
Text->m_Size.x = Text->m_Size.y = m_textSize; Text->m_Size.x = Text->m_Size.y = m_textSize;
Text->m_Orient = m_textOrientation; Text->m_Orient = m_textOrientation;
Text->m_Pos = GetScreen()->m_Curseur;
NEGATE( Text->m_Pos.y );
// Enter the graphic text info // Enter the graphic text info
DrawPanel->m_IgnoreMouseEvents = true; DrawPanel->m_IgnoreMouseEvents = true;
...@@ -279,18 +163,13 @@ LIB_DRAW_ITEM* WinEDA_LibeditFrame::CreateGraphicItem( LIB_COMPONENT* LibEntry, ...@@ -279,18 +163,13 @@ LIB_DRAW_ITEM* WinEDA_LibeditFrame::CreateGraphicItem( LIB_COMPONENT* LibEntry,
{ {
SAFE_DELETE( Text ); SAFE_DELETE( Text );
m_drawItem = NULL; m_drawItem = NULL;
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
} }
else else
{ {
StartMoveDrawSymbol( DC ); m_drawItem = Text;
Text->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, g_XorMode, NULL,
DefaultTransformMatrix );
} }
break;
} }
break;
default: default:
DisplayError( this, wxT( "WinEDA_LibeditFrame::CreateGraphicItem() error" ) ); DisplayError( this, wxT( "WinEDA_LibeditFrame::CreateGraphicItem() error" ) );
return NULL; return NULL;
...@@ -298,11 +177,22 @@ LIB_DRAW_ITEM* WinEDA_LibeditFrame::CreateGraphicItem( LIB_COMPONENT* LibEntry, ...@@ -298,11 +177,22 @@ LIB_DRAW_ITEM* WinEDA_LibeditFrame::CreateGraphicItem( LIB_COMPONENT* LibEntry,
if( m_drawItem ) if( m_drawItem )
{ {
m_drawItem->m_Flags |= IS_NEW; m_drawItem->BeginEdit( IS_NEW, drawPos );
m_drawItem->SetWidth( m_drawLineWidth );
m_drawItem->m_Fill = m_drawFillStyle;
if( m_drawSpecificUnit ) if( m_drawSpecificUnit )
m_drawItem->m_Unit = m_unit; m_drawItem->m_Unit = m_unit;
if( m_drawSpecificConvert ) if( m_drawSpecificConvert )
m_drawItem->m_Convert = m_convert; m_drawItem->m_Convert = m_convert;
m_savedComponent = new LIB_COMPONENT( *m_component );
}
else
{
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
return NULL;
} }
DrawPanel->MouseToCursorSchema(); DrawPanel->MouseToCursorSchema();
...@@ -319,43 +209,15 @@ void WinEDA_LibeditFrame::GraphicItemBeginDraw( wxDC* DC ) ...@@ -319,43 +209,15 @@ void WinEDA_LibeditFrame::GraphicItemBeginDraw( wxDC* DC )
if( m_drawItem == NULL ) if( m_drawItem == NULL )
return; return;
switch( m_drawItem->Type() ) wxPoint pos = GetScreen()->GetCursorDrawPosition();
{
case COMPONENT_ARC_DRAW_TYPE:
if( arcState.stateDrawArc == 1 )
{
SymbolDisplayDraw( DrawPanel, DC, FALSE );
arcState.stateDrawArc = 2;
SymbolDisplayDraw( DrawPanel, DC, FALSE );
break;
}
if( arcState.stateDrawArc > 1 )
{
EndDrawGraphicItem( DC );
return;
}
break;
case COMPONENT_CIRCLE_DRAW_TYPE:
case COMPONENT_RECT_DRAW_TYPE:
case COMPONENT_GRAPHIC_TEXT_DRAW_TYPE:
EndDrawGraphicItem( DC );
return;
case COMPONENT_POLYLINE_DRAW_TYPE: if( m_drawItem->ContinueEdit( pos ) )
{ {
wxPoint pos = GetScreen()->m_Curseur; m_drawItem->Draw( DrawPanel, DC, pos, -1, g_XorMode, NULL, DefaultTransform );
NEGATE( pos.y ); return;
( (LIB_POLYLINE*) m_drawItem )->AddPoint( pos );
} }
break;
case COMPONENT_LINE_DRAW_TYPE: EndDrawGraphicItem( DC );
break;
default:
;
}
} }
...@@ -372,19 +234,9 @@ static void RedrawWhileMovingCursor( WinEDA_DrawPanel* panel, wxDC* DC, bool era ...@@ -372,19 +234,9 @@ static void RedrawWhileMovingCursor( WinEDA_DrawPanel* panel, wxDC* DC, bool era
return; return;
BASE_SCREEN* Screen = panel->GetScreen(); BASE_SCREEN* Screen = panel->GetScreen();
wxPoint pos;
/* Erase shape in the old position*/ item->Draw( panel, DC, Screen->GetCursorDrawPosition(), -1, g_XorMode, NULL,
if( erase ) DefaultTransform );
{
pos = ItemPreviousPos - StartCursor;
item->Draw( panel, DC, pos, -1, g_XorMode, NULL, DefaultTransformMatrix );
}
/* Redraw moved shape */
pos = Screen->m_Curseur - StartCursor;
item->Draw( panel, DC, pos, -1, g_XorMode, NULL, DefaultTransformMatrix );
ItemPreviousPos = Screen->m_Curseur;
} }
...@@ -395,13 +247,14 @@ void WinEDA_LibeditFrame::StartMoveDrawSymbol( wxDC* DC ) ...@@ -395,13 +247,14 @@ void WinEDA_LibeditFrame::StartMoveDrawSymbol( wxDC* DC )
SetCursor( wxCURSOR_HAND ); SetCursor( wxCURSOR_HAND );
m_drawItem->m_Flags |= IS_MOVED; if( m_drawItem->m_Unit != m_unit )
StartCursor = GetScreen()->m_Curseur; m_drawItem->m_Unit = m_unit;
InitPosition = m_drawItem->GetPosition();
ItemPreviousPos = GetScreen()->m_Curseur; m_savedComponent = new LIB_COMPONENT( *m_component );
m_drawItem->BeginEdit( IS_MOVED, GetScreen()->GetCursorDrawPosition() );
DrawPanel->ManageCurseur = RedrawWhileMovingCursor; DrawPanel->ManageCurseur = RedrawWhileMovingCursor;
DrawPanel->ForceCloseManageCurseur = AbortSymbolTraceOn; DrawPanel->ForceCloseManageCurseur = AbortSymbolTraceOn;
DrawPanel->ManageCurseur( DrawPanel, DC, TRUE ); DrawPanel->ManageCurseur( DrawPanel, DC, true );
} }
...@@ -411,400 +264,25 @@ void WinEDA_LibeditFrame::StartModifyDrawSymbol( wxDC* DC ) ...@@ -411,400 +264,25 @@ void WinEDA_LibeditFrame::StartModifyDrawSymbol( wxDC* DC )
if( m_drawItem == NULL ) if( m_drawItem == NULL )
return; return;
// TODO Check if this is really required m_savedComponent = new LIB_COMPONENT( *m_component );
StartCursor = GetScreen()->m_Curseur; m_drawItem->BeginEdit( IS_RESIZED, GetScreen()->GetCursorDrawPosition() );
InitPosition = m_drawItem->GetPosition();
ItemPreviousPos = GetScreen()->m_Curseur;
switch( m_drawItem->Type() )
{
case COMPONENT_ARC_DRAW_TYPE:
{
wxPoint cursor = StartCursor;
cursor.y = -cursor.y;
// The arc center point has to be rotated with while adjusting the
// start or end point, determine the side of this point and the distance
// from the start / end point
wxPoint startPoint = ( (LIB_ARC*) m_drawItem )->m_ArcStart;
wxPoint endPoint = ( (LIB_ARC*) m_drawItem )->m_ArcEnd;
wxPoint centerPoint = ( (LIB_ARC*) m_drawItem )->m_Pos;
wxPoint middlePoint = wxPoint( (startPoint.x + endPoint.x) / 2,
(startPoint.y + endPoint.y) / 2 );
wxPoint centerVector = centerPoint - middlePoint;
wxPoint startEndVector = TwoPointVector( startPoint, endPoint );
arcState.distanceCenter = EuclideanNorm( centerVector );
// Determine on which side is the center point
arcState.direction = CrossProduct( startEndVector, centerVector ) ? 1 : -1;
arcState.startPoint = startPoint;
arcState.endPoint = endPoint;
// Save the old values
savedAttributes.startPoint = startPoint;
savedAttributes.endPoint = endPoint;
savedAttributes.centerPoint = centerPoint;
// Drag either the start, end point or the outline
if( HitTestPoints( startPoint, cursor, MINIMUM_SELECTION_DISTANCE ) )
{
arcState.selectedPoint = START_POINT;
}
else if( HitTestPoints( endPoint, cursor, MINIMUM_SELECTION_DISTANCE ) )
{
arcState.selectedPoint = END_POINT;
}
else
arcState.selectedPoint = OUTLINE;
arcState.stateDrawArc = 0;
m_drawItem->m_Flags |= IS_RESIZED;
}
break;
case COMPONENT_RECT_DRAW_TYPE:
{
// Save old attributes
savedAttributes.startPoint = ( (LIB_RECTANGLE*) m_drawItem )->m_Pos;
savedAttributes.endPoint = ( (LIB_RECTANGLE*) m_drawItem )->m_End;
// Resize rectangle
m_drawItem->m_Flags |= IS_RESIZED;
// If the cursor is not on the rectangle edge point,
// lock the width or height
wxPoint rectEnd = ( (LIB_RECTANGLE*) m_drawItem )->m_End;
wxPoint rectStart = ( (LIB_RECTANGLE*) m_drawItem )->m_Pos;
wxPoint cursor = StartCursor;
cursor.y = -cursor.y;
( (LIB_RECTANGLE*) m_drawItem )->m_isStartPointSelected =
abs( rectStart.x - cursor.x ) < MINIMUM_SELECTION_DISTANCE
|| abs( rectStart.y - cursor.y ) < MINIMUM_SELECTION_DISTANCE;
if( ( (LIB_RECTANGLE*) m_drawItem )->m_isStartPointSelected )
{
( (LIB_RECTANGLE*) m_drawItem )->m_isWidthLocked =
abs( rectStart.x - cursor.x ) >= MINIMUM_SELECTION_DISTANCE;
( (LIB_RECTANGLE*) m_drawItem )->m_isHeightLocked =
abs( rectStart.y - cursor.y ) >= MINIMUM_SELECTION_DISTANCE;
}
else
{
( (LIB_RECTANGLE*) m_drawItem )->m_isWidthLocked =
abs( rectEnd.x - cursor.x ) >= MINIMUM_SELECTION_DISTANCE;
( (LIB_RECTANGLE*) m_drawItem )->m_isHeightLocked =
abs( rectEnd.y - cursor.y ) >= MINIMUM_SELECTION_DISTANCE;
}
}
break;
case COMPONENT_CIRCLE_DRAW_TYPE:
savedAttributes.radius = ( (LIB_CIRCLE*) m_drawItem )->m_Radius;
m_drawItem->m_Flags |= IS_RESIZED;
break;
case COMPONENT_POLYLINE_DRAW_TYPE:
{
// Drag one edge point of the polyline
m_drawItem->m_Flags |= IS_RESIZED;
// Find the nearest edge point to be dragged
wxPoint cursor = StartCursor;
wxPoint startPoint = ( ( (LIB_POLYLINE*) m_drawItem )->m_PolyPoints )[0];
cursor.y = NEGATE( cursor.y );
// Begin with the first list point as nearest point
int index = 0;
( (LIB_POLYLINE*) m_drawItem )->m_ModifyIndex = 0;
savedAttributes.startPoint = startPoint;
// First distance is the current minimum distance
int distanceMin = (cursor - startPoint).x * (cursor - startPoint).x
+ (cursor - startPoint).y * (cursor - startPoint).y;
// Find the right index of the point to be dragged
BOOST_FOREACH( wxPoint point, ( ( (LIB_POLYLINE*) m_drawItem )->m_PolyPoints ) )
{
int distancePoint = (cursor - point).x * (cursor - point).x +
(cursor - point).y * (cursor - point).y;
if( distancePoint < distanceMin )
{
// Save point
savedAttributes.startPoint = point;
( (LIB_POLYLINE*) m_drawItem )->m_ModifyIndex = index;
distanceMin = distancePoint;
}
index++;
}
}
break;
default:
break;
}
DrawPanel->ManageCurseur = SymbolDisplayDraw; DrawPanel->ManageCurseur = SymbolDisplayDraw;
DrawPanel->ForceCloseManageCurseur = AbortSymbolTraceOn; DrawPanel->ForceCloseManageCurseur = AbortSymbolTraceOn;
DrawPanel->ManageCurseur( DrawPanel, DC, TRUE ); DrawPanel->ManageCurseur( DrawPanel, DC, true );
} }
//! @brief Manage mouse events when creating new graphic object or modifying an graphic object. //! @brief Manage mouse events when creating new graphic object or modifying an graphic object.
static void SymbolDisplayDraw( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ) static void SymbolDisplayDraw( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
{ {
int dx, dy;
int DrawMode = g_XorMode;
BASE_SCREEN* Screen = panel->GetScreen(); BASE_SCREEN* Screen = panel->GetScreen();
wxPoint currentCursorPosition = Screen->m_Curseur; LIB_DRAW_ITEM* item = ( (WinEDA_LibeditFrame*) panel->GetParent() )->GetDrawItem();
FILL_T fillStyle = NO_FILL;
LIB_DRAW_ITEM* item;
item = ( (WinEDA_LibeditFrame*) panel->GetParent() )->GetDrawItem();
if( item == NULL ) if( item == NULL )
return; return;
fillStyle = ( (WinEDA_LibeditFrame*) panel->GetParent() )->GetFillStyle(); item->Draw( panel, DC, Screen->GetCursorDrawPosition(), -1, g_XorMode, NULL,
DefaultTransform );
NEGATE( currentCursorPosition.y );
GRSetDrawMode( DC, DrawMode );
if( erase )
{
if( arcState.stateDrawArc == 1 )
{
int Color = ReturnLayerColor( LAYER_DEVICE );
GRLine( &panel->m_ClipBox, DC, arcState.startPoint.x, -arcState.startPoint.y,
arcState.endPoint.x, -arcState.endPoint.y, 0, Color );
}
else
{
item->Draw( panel, DC, wxPoint( 0, 0 ), -1, DrawMode, NULL,
DefaultTransformMatrix );
if( item->Type() == COMPONENT_ARC_DRAW_TYPE && item->m_Flags != IS_RESIZED )
{
int Color = ReturnLayerColor( LAYER_DEVICE );
GRDashedLine( &panel->m_ClipBox, DC, arcState.startPoint.x, -arcState.startPoint.y,
( (LIB_ARC*) item )->m_Pos.x,
-( (LIB_ARC*) item )->m_Pos.y,
0, Color );
GRDashedLine( &panel->m_ClipBox, DC, arcState.endPoint.x, -arcState.endPoint.y,
( (LIB_ARC*) item )->m_Pos.x,
-( (LIB_ARC*) item )->m_Pos.y,
0, Color );
}
}
}
switch( item->Type() )
{
case COMPONENT_ARC_DRAW_TYPE:
if( item->m_Flags == IS_RESIZED )
{
wxPoint newCenterPoint;
// Choose the point of the arc to be adjusted
if( arcState.selectedPoint == START_POINT )
{
arcState.startPoint = currentCursorPosition;
arcState.endPoint = ( (LIB_ARC*) item )->m_ArcEnd;
}
else if( arcState.selectedPoint == END_POINT )
{
arcState.endPoint = currentCursorPosition;
arcState.startPoint = ( (LIB_ARC*) item )->m_ArcStart;
}
else
{
// Use the cursor for adjusting the arc curvature
arcState.startPoint = ( (LIB_ARC*) item )->m_ArcStart;
arcState.endPoint = ( (LIB_ARC*) item )->m_ArcEnd;
wxPoint middlePoint = wxPoint( (arcState.startPoint.x + arcState.endPoint.x) / 2,
(arcState.startPoint.y + arcState.endPoint.y) / 2 );
// If the distance is too small, use the old center point
// else the new center point is calculated over the three points start/end/cursor
if( DistanceLinePoint( arcState.startPoint, arcState.endPoint,
currentCursorPosition )
> MINIMUM_SELECTION_DISTANCE )
{
newCenterPoint = ComputeCircumCenter( arcState.startPoint,
currentCursorPosition,
arcState.endPoint );
}
else
{
newCenterPoint = ( (LIB_ARC*) item )->m_Pos;
}
// Determine if the arc angle is larger than 180 degrees -> this happens if both
// points (cursor position, center point) lie on the same side of the vector
// start-end
int crossA = CrossProduct( TwoPointVector( arcState.startPoint,
arcState.endPoint ),
TwoPointVector( arcState.endPoint,
currentCursorPosition ) );
int crossB = CrossProduct( TwoPointVector( arcState.startPoint,
arcState.endPoint ),
TwoPointVector( arcState.endPoint, newCenterPoint ) );
bool isLarger180degrees = ( crossA < 0 && crossB < 0 ) ||
( crossA >= 0 && crossB >= 0 );
if( isLarger180degrees )
newCenterPoint = ( (LIB_ARC*) item )->m_Pos;
}
if( arcState.selectedPoint == START_POINT || arcState.selectedPoint == END_POINT )
{
// Compute the new center point when the start/end points are modified
wxPoint middlePoint = wxPoint( (arcState.startPoint.x + arcState.endPoint.x) / 2,
(arcState.startPoint.y + arcState.endPoint.y) / 2 );
wxPoint startEndVector = TwoPointVector( arcState.startPoint, arcState.endPoint );
wxPoint perpendicularVector = wxPoint( -startEndVector.y, startEndVector.x );
double lengthPerpendicularVector = EuclideanNorm( perpendicularVector );
// prevent too large values, division / 0
if( lengthPerpendicularVector < 1e-1 )
lengthPerpendicularVector = 1e-1;
perpendicularVector.x = (int) ( (double) perpendicularVector.x *
arcState.distanceCenter /
lengthPerpendicularVector ) * arcState.direction;
perpendicularVector.y = (int) ( (double) perpendicularVector.y *
arcState.distanceCenter /
lengthPerpendicularVector ) * arcState.direction;
newCenterPoint = middlePoint + perpendicularVector;
( (LIB_ARC*) item )->m_ArcStart = arcState.startPoint;
( (LIB_ARC*) item )->m_ArcEnd = arcState.endPoint;
}
( (LIB_ARC*) item )->m_Pos = newCenterPoint;
ComputeArcRadiusAngles( (LIB_ARC*) item );
}
else
{
if( arcState.stateDrawArc == 1 )
{
arcState.endPoint.x = currentCursorPosition.x;
arcState.endPoint.y = currentCursorPosition.y;
}
if( arcState.stateDrawArc == 2 )
{
ComputeArc( (LIB_ARC*) item, Screen->m_Curseur );
}
item->m_Fill = fillStyle;
}
break;
case COMPONENT_CIRCLE_DRAW_TYPE:
dx = ( (LIB_CIRCLE*) item )->m_Pos.x - currentCursorPosition.x;
dy = ( (LIB_CIRCLE*) item )->m_Pos.y - currentCursorPosition.y;
( (LIB_CIRCLE*) item )->m_Radius =
(int) sqrt( ( (double) dx * dx ) + ( (double) dy * dy ) );
item->m_Fill = fillStyle;
break;
case COMPONENT_RECT_DRAW_TYPE:
if( ( (LIB_RECTANGLE*) item )->m_isHeightLocked )
{
if( ( (LIB_RECTANGLE*) item )->m_isStartPointSelected )
{
( (LIB_RECTANGLE*) item )->m_Pos.x = currentCursorPosition.x;
}
else
{
( (LIB_RECTANGLE*) item )->m_End.x = currentCursorPosition.x;
}
}
else if( ( (LIB_RECTANGLE*) item )->m_isWidthLocked )
{
if( ( (LIB_RECTANGLE*) item )->m_isStartPointSelected )
{
( (LIB_RECTANGLE*) item )->m_Pos.y = currentCursorPosition.y;
}
else
{
( (LIB_RECTANGLE*) item )->m_End.y = currentCursorPosition.y;
}
}
else
{
if( ( (LIB_RECTANGLE*) item )->m_isStartPointSelected )
{
( (LIB_RECTANGLE*) item )->m_Pos = currentCursorPosition;
}
else
{
( (LIB_RECTANGLE*) item )->m_End = currentCursorPosition;
}
}
item->m_Fill = fillStyle;
break;
case COMPONENT_POLYLINE_DRAW_TYPE:
{
unsigned idx;
if( item->m_Flags == IS_RESIZED )
idx = ( (LIB_POLYLINE*) item )->m_ModifyIndex;
else
idx = ( (LIB_POLYLINE*) item )->GetCornerCount() - 1;
( (LIB_POLYLINE*) item )->m_PolyPoints[idx] = currentCursorPosition;
item->m_Fill = fillStyle;
}
break;
case COMPONENT_GRAPHIC_TEXT_DRAW_TYPE:
break;
default:
;
}
if( arcState.stateDrawArc == 1 )
{
int Color = ReturnLayerColor( LAYER_DEVICE );
GRLine( &panel->m_ClipBox, DC, arcState.startPoint.x, -arcState.startPoint.y,
arcState.endPoint.x, -arcState.endPoint.y, 0, Color );
}
else
{
item->Draw( panel, DC, wxPoint( 0, 0 ), -1, DrawMode, NULL, DefaultTransformMatrix );
if( item->Type() == COMPONENT_ARC_DRAW_TYPE && item->m_Flags != IS_RESIZED )
{
int Color = ReturnLayerColor( LAYER_DEVICE );
GRDashedLine( &panel->m_ClipBox, DC, arcState.startPoint.x, -arcState.startPoint.y,
( (LIB_ARC*) item )->m_Pos.x,
-( (LIB_ARC*) item )->m_Pos.y,
0, Color );
GRDashedLine( &panel->m_ClipBox, DC, arcState.endPoint.x, -arcState.endPoint.y,
( (LIB_ARC*) item )->m_Pos.x,
-( (LIB_ARC*) item )->m_Pos.y,
0, Color );
}
}
} }
...@@ -816,282 +294,24 @@ void WinEDA_LibeditFrame::EndDrawGraphicItem( wxDC* DC ) ...@@ -816,282 +294,24 @@ void WinEDA_LibeditFrame::EndDrawGraphicItem( wxDC* DC )
if( m_component == NULL || m_drawItem == NULL ) if( m_component == NULL || m_drawItem == NULL )
return; return;
if( m_drawItem->Type() == COMPONENT_ARC_DRAW_TYPE )
{
if( arcState.stateDrawArc == 1 ) /* Trace arc under way must be completed. */
{
DisplayError( this, wxT( "Arc in progress.." ) );
return;
}
else
{
if( ( m_drawItem->m_Flags & IS_MOVED ) == 0 )
SymbolDisplayDraw( DrawPanel, DC, FALSE );
}
}
arcState.stateDrawArc = 0;
if( m_drawItem->m_Flags & IS_NEW )
{
SaveCopyInUndoList( m_component );
m_component->AddDrawItem( m_drawItem );
switch( m_drawItem->Type() )
{
case COMPONENT_ARC_DRAW_TYPE:
( (LIB_ARC*) m_drawItem )->m_Fill = m_drawFillStyle;
break;
case COMPONENT_CIRCLE_DRAW_TYPE:
( (LIB_CIRCLE*) m_drawItem )->m_Fill = m_drawFillStyle;
break;
case COMPONENT_RECT_DRAW_TYPE:
( (LIB_RECTANGLE*) m_drawItem )->m_Fill = m_drawFillStyle;
( (LIB_RECTANGLE*) m_drawItem )->m_isHeightLocked = false;
( (LIB_RECTANGLE*) m_drawItem )->m_isWidthLocked = false;
break;
case COMPONENT_POLYLINE_DRAW_TYPE:
( (LIB_POLYLINE*) m_drawItem )->m_Fill = m_drawFillStyle;
break;
case COMPONENT_PIN_DRAW_TYPE:
case COMPONENT_LINE_DRAW_TYPE:
case COMPONENT_GRAPHIC_TEXT_DRAW_TYPE:
break;
default:
;
}
}
if( m_ID_current_state ) if( m_ID_current_state )
SetCursor( wxCURSOR_PENCIL ); SetCursor( wxCURSOR_PENCIL );
else else
SetCursor( wxCURSOR_ARROW ); SetCursor( wxCURSOR_ARROW );
if( m_drawItem->m_Flags & IS_MOVED ) SaveCopyInUndoList( m_savedComponent );
{ DeleteSavedComponent();
wxPoint pos;
pos.x = GetScreen()->m_Curseur.x + InitPosition.x - StartCursor.x,
pos.y = GetScreen()->m_Curseur.y - InitPosition.y - StartCursor.y;
NEGATE( pos.y );
m_drawItem->Move( pos );
}
m_component->Draw( DrawPanel, DC, wxPoint( 0, 0 ), m_unit, m_convert, GR_DEFAULT_DRAWMODE ); if( m_drawItem->IsNew() )
m_component->AddDrawItem( m_drawItem );
m_drawItem->EndEdit( GetScreen()->GetCursorDrawPosition() );
m_drawItem->m_Flags = 0;
m_drawItem = NULL; m_drawItem = NULL;
OnModify( ); OnModify();
DrawPanel->ManageCurseur = NULL; DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL; DrawPanel->ForceCloseManageCurseur = NULL;
} DrawPanel->Refresh();
//! @brief Compute the missing attributes (angles, radius),
// when the three points (start, end, center) given
//! @param arc Arc to be modified
static void ComputeArcRadiusAngles( LIB_ARC* arc )
{
wxPoint centerStartVector = TwoPointVector( arc->m_Pos, arc->m_ArcStart );
wxPoint centerEndVector = TwoPointVector( arc->m_Pos, arc->m_ArcEnd );
arc->m_Radius = wxRound( EuclideanNorm( centerStartVector ) );
arc->m_t1 = (int) ( atan2( (double) centerStartVector.y,
(double) centerStartVector.x ) * 1800 / M_PI );
arc->m_t2 = (int) ( atan2( (double) centerEndVector.y,
(double) centerEndVector.x ) * 1800 / M_PI );
NORMALIZE_ANGLE( arc->m_t1 );
NORMALIZE_ANGLE( arc->m_t2 ); // angles = 0 .. 3600
// Restrict angle to less than 180 to avoid PBS display mirror
// Trace because it is assumed that the arc is less than 180 deg to find
// orientation after rotate or mirror.
if( (arc->m_t2 - arc->m_t1) > 1800 )
arc->m_t2 -= 3600;
else if( (arc->m_t2 - arc->m_t1) <= -1800 )
arc->m_t2 += 3600;
wxString msg;
int angle = arc->m_t2 - arc->m_t1;
msg.Printf( _( "Arc %.1f deg" ), (float) angle / 10 );
WinEDA_SchematicFrame* frame = (WinEDA_SchematicFrame*) wxGetApp().GetTopWindow();
frame->m_LibeditFrame->PrintMsg( msg );
while( (arc->m_t2 - arc->m_t1) >= 1800 )
{
arc->m_t2--;
arc->m_t1++;
}
while( (arc->m_t1 - arc->m_t2) >= 1800 )
{
arc->m_t2++;
arc->m_t1--;
}
NORMALIZE_ANGLE( arc->m_t1 );
}
/*
* Routine for adjusting the parameters of the arc currently being drawn.
* Calculates the center, radius, angles for the arc current
* Passes through the points arcState.startPoint.x, arcState.endPoint.x Y and Y with the
* nearest center of the mouse position.
* Note: The center is obviously not on the grid
*/
static void ComputeArc( LIB_ARC* DrawItem, wxPoint ArcCentre )
{
int dx, dy;
int cX, cY;
int angle;
cX = ArcCentre.x;
cY = ArcCentre.y;
cY = -cY; /* Attention to the orientation of the axis Y. */
/* Calculating cX and cY for the arc passes through arcState.startPoint.x, arcState.endPoint.x,
* X and Y */
dx = arcState.endPoint.x - arcState.startPoint.x;
dy = arcState.endPoint.y - arcState.startPoint.y;
cX -= arcState.startPoint.x;
cY -= arcState.startPoint.y;
angle = (int) ( atan2( (double) dy, (double) dx ) * 1800 / M_PI );
RotatePoint( &dx, &dy, angle ); /* The segment dx, dy is horizontal
* -> Length = dx, dy = 0 */
RotatePoint( &cX, &cY, angle );
cX = dx / 2; /* cX, cY is on the median segment 0.0 a dx, 0 */
RotatePoint( &cX, &cY, -angle );
cX += arcState.startPoint.x;
cY += arcState.startPoint.y;
DrawItem->m_Pos.x = cX;
DrawItem->m_Pos.y = cY;
dx = arcState.startPoint.x - DrawItem->m_Pos.x;
dy = arcState.startPoint.y - DrawItem->m_Pos.y;
DrawItem->m_Radius = (int) sqrt( ( (double) dx * dx ) + ( (double) dy * dy ) );
DrawItem->m_t1 = (int) ( atan2( (double) dy, (double) dx ) * 1800 / M_PI );
dx = arcState.endPoint.x - DrawItem->m_Pos.x;
dy = arcState.endPoint.y - DrawItem->m_Pos.y;
DrawItem->m_t2 = (int) ( atan2( (double) dy, (double) dx ) * 1800 / M_PI );
DrawItem->m_ArcStart.x = arcState.startPoint.x;
DrawItem->m_ArcStart.y = arcState.startPoint.y;
DrawItem->m_ArcEnd.x = arcState.endPoint.x;
DrawItem->m_ArcEnd.y = arcState.endPoint.y;
NORMALIZE_ANGLE( DrawItem->m_t1 );
NORMALIZE_ANGLE( DrawItem->m_t2 ); // angles = 0 .. 3600
// Restrict angle to less than 180 to avoid PBS display mirror
// Trace because it is assumed that the arc is less than 180 deg to find
// orientation after rotate or mirror.
if( (DrawItem->m_t2 - DrawItem->m_t1) > 1800 )
DrawItem->m_t2 -= 3600;
else if( (DrawItem->m_t2 - DrawItem->m_t1) <= -1800 )
DrawItem->m_t2 += 3600;
wxString msg;
angle = DrawItem->m_t2 - DrawItem->m_t1;
msg.Printf( _( "Arc %.1f deg" ), (float) angle / 10 );
WinEDA_SchematicFrame* frame = (WinEDA_SchematicFrame*) wxGetApp().GetTopWindow();
frame->m_LibeditFrame->PrintMsg( msg );
while( (DrawItem->m_t2 - DrawItem->m_t1) >= 1800 )
{
DrawItem->m_t2--;
DrawItem->m_t1++;
}
while( (DrawItem->m_t1 - DrawItem->m_t2) >= 1800 )
{
DrawItem->m_t2++;
DrawItem->m_t1--;
}
NORMALIZE_ANGLE( DrawItem->m_t1 );
NORMALIZE_ANGLE( DrawItem->m_t2 );
}
//! @brief Given three points A B C, compute the circumcenter of the resulting triangle
//! reference: http://en.wikipedia.org/wiki/Circumscribed_circle
//! Coordinates of circumcenter in Cartesian coordinates
static wxPoint ComputeCircumCenter( wxPoint A, wxPoint B, wxPoint C )
{
double circumCenterX, circumCenterY;
double Ax = (double) A.x;
double Ay = (double) A.y;
double Bx = (double) B.x;
double By = (double) B.y;
double Cx = (double) C.x;
double Cy = (double) C.y;
wxPoint circumCenter;
double D = 2.0 * ( Ax * ( By - Cy ) + Bx * ( Cy - Ay ) + Cx * ( Ay - By ) );
// prevent division / 0
if( fabs( D ) < 1e-7 )
D = 1e-7;
circumCenterX = ( (Ay * Ay + Ax * Ax) * (By - Cy) +
(By * By + Bx * Bx) * (Cy - Ay) +
(Cy * Cy + Cx * Cx) * (Ay - By) ) / D;
circumCenterY = ( (Ay * Ay + Ax * Ax) * (Cx - Bx) +
(By * By + Bx * Bx) * (Ax - Cx) +
(Cy * Cy + Cx * Cx) * (Bx - Ax) ) / D;
circumCenter.x = (int) circumCenterX;
circumCenter.y = (int) circumCenterY;
return circumCenter;
}
/*
* Used for deleting last entered segment while creating a Polyline
*/
void WinEDA_LibeditFrame::DeleteDrawPoly( wxDC* DC )
{
if( m_drawItem == NULL || m_drawItem->Type() != COMPONENT_POLYLINE_DRAW_TYPE )
return;
LIB_POLYLINE* Poly = (LIB_POLYLINE*) m_drawItem;
m_drawItem->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, g_XorMode, NULL,
DefaultTransformMatrix );
// First segment is kept, only its end point is changed
while( Poly->GetCornerCount() > 2 )
{
Poly->m_PolyPoints.pop_back();
unsigned idx = Poly->GetCornerCount() - 1;
wxPoint point = GetScreen()->m_Curseur;
NEGATE( point.y );
if( Poly->m_PolyPoints[idx] != point )
{
Poly->m_PolyPoints[idx] = point;
break;
}
}
m_drawItem->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, g_XorMode, NULL,
DefaultTransformMatrix );
} }
#include "macros.h"
#include "transform.h"
TRANSFORM& TRANSFORM::operator=( const TRANSFORM& aTransform )
{
if( this == &aTransform ) // Check for self assingnemt;
return *this;
x1 = aTransform.x1;
y1 = aTransform.y1;
x2 = aTransform.x2;
y2 = aTransform.y2;
return *this;
}
bool TRANSFORM::operator==( const TRANSFORM& aTransform ) const
{
return ( x1 == aTransform.x1 &&
y1 == aTransform.y1 &&
x2 == aTransform.x2 &&
y2 == aTransform.y2 );
}
wxPoint TRANSFORM::TransformCoordinate( const wxPoint& aPoint ) const
{
return wxPoint( ( x1 * aPoint.x ) + ( y1 * aPoint.y ),
( x2 * aPoint.x ) + ( y2 * aPoint.y ) );
}
bool TRANSFORM::MapAngles( int* aAngle1, int* aAngle2 ) const
{
wxCHECK_MSG( aAngle1 != NULL && aAngle2 != NULL, false,
wxT( "Cannot map NULL point angles." ) );
int Angle, Delta;
double x, y, t;
bool swap = false;
Delta = *aAngle2 - *aAngle1;
if( Delta >= 1800 )
{
*aAngle1 -= 1;
*aAngle2 += 1;
}
x = cos( *aAngle1 * M_PI / 1800.0 );
y = sin( *aAngle1 * M_PI / 1800.0 );
t = x * x1 + y * y1;
y = x * x2 + y * y2;
x = t;
*aAngle1 = (int) ( atan2( y, x ) * 1800.0 / M_PI + 0.5 );
x = cos( *aAngle2 * M_PI / 1800.0 );
y = sin( *aAngle2 * M_PI / 1800.0 );
t = x * x1 + y * y1;
y = x * x2 + y * y2;
x = t;
*aAngle2 = (int) ( atan2( y, x ) * 1800.0 / M_PI + 0.5 );
NORMALIZE_ANGLE( *aAngle1 );
NORMALIZE_ANGLE( *aAngle2 );
if( *aAngle2 < *aAngle1 )
*aAngle2 += 3600;
if( *aAngle2 - *aAngle1 > 1800 ) /* Need to swap the two angles. */
{
Angle = (*aAngle1);
*aAngle1 = (*aAngle2);
*aAngle2 = Angle;
NORMALIZE_ANGLE( *aAngle1 );
NORMALIZE_ANGLE( *aAngle2 );
if( *aAngle2 < *aAngle1 )
*aAngle2 += 3600;
swap = true;
}
if( Delta >= 1800 )
{
*aAngle1 += 1;
*aAngle2 -= 1;
}
return swap;
}
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2007-2010 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _TRANSFORM_H_
#define _TRANSFORM_H_
#include <wx/gdicmn.h>
/**
* Class for tranforming drawing coordinates for a wxDC device context.
*
* This probably should be a base class with all pure methods and a derived class
* named WXDC_TRANFORM be created. Then in the future if some new device context
* is used, a new transform could be derived from the base class and all the drawable
* objects would have to do is provide overloaded draw methods to use the new transorm.
*/
class TRANSFORM
{
public:
int x1;
int y1;
int x2;
int y2;
/**
* The default construct creates a tranform that draws object is the normal orientation.
*/
TRANSFORM() : x1( 1 ), y1( 0 ), x2( 0 ), y2( -1 ) {}
TRANSFORM( int x1, int y1, int x2, int y2 ) : x1( x1 ), y1( y1 ), x2( x2 ), y2( y2 ) {}
TRANSFORM& operator=( const TRANSFORM& aTransform );
bool operator==( const TRANSFORM& aTransform ) const;
/**
* Calculate new coordinate according to the transform.
*
* @param aPosition = The position to transform
* @return The transformed coordinate.
*/
wxPoint TransformCoordinate( const wxPoint& aPoint ) const;
/**
* Calculate new angles according to the transform.
*
* @param aAngle1 = The first angle to transform
* @param aAngle2 = The second angle to transform
* @return True if the angles were swapped during the transform.
*/
bool MapAngles( int* aAngle1, int* aAngle2 ) const;
};
#endif // _TRANSFORM_H_
...@@ -373,6 +373,9 @@ public: ...@@ -373,6 +373,9 @@ public:
m_Status = new_status; m_Status = new_status;
} }
void SetFlags( int aFlags ) { m_Flags = aFlags; }
int GetFlags() { return m_Flags; }
/** /**
* Function DisplayInfo * Function DisplayInfo
......
...@@ -167,6 +167,16 @@ public: ...@@ -167,6 +167,16 @@ public:
*/ */
wxPoint CursorRealPosition( const wxPoint& ScreenPos ); wxPoint CursorRealPosition( const wxPoint& ScreenPos );
/**
* Return the current cursor position in drawing coordinates.
*
* This call inverts the Y axis coordinated of m_Curseur to correct for the difference
* between the wxWidgets GDI and the Kicad drawing coordinates.
*
* @return - The cursor position in drawing coordinates.
*/
wxPoint GetCursorDrawPosition() { return wxPoint( m_Curseur.x, -m_Curseur.y ); }
/* general Undo/Redo command control */ /* general Undo/Redo command control */
/** function ClearUndoORRedoList (virtual). /** function ClearUndoORRedoList (virtual).
...@@ -180,10 +190,7 @@ public: ...@@ -180,10 +190,7 @@ public:
* old commands this will empty the list of commands. * old commands this will empty the list of commands.
* Commands are deleted from the older to the last. * Commands are deleted from the older to the last.
*/ */
virtual void ClearUndoORRedoList( virtual void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ) = 0;
UNDO_REDO_CONTAINER& aList,
int
aItemCount = -1 ) = 0;
/** Function ClearUndoRedoList /** Function ClearUndoRedoList
* clear undo and redo list, using ClearUndoORRedoList() * clear undo and redo list, using ClearUndoORRedoList()
......
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
#ifndef MACROS_H #ifndef MACROS_H
#define MACROS_H #define MACROS_H
#include <wx/wx.h>
#if wxUSE_UNICODE #if wxUSE_UNICODE
#define CONV_TO_UTF8( wxstring ) ( (const char*) wxConvCurrent->cWX2MB( wxstring ) ) #define CONV_TO_UTF8( wxstring ) ( (const char*) wxConvCurrent->cWX2MB( wxstring ) )
#define CONV_FROM_UTF8( utf8string ) ( wxConvCurrent->cMB2WC( utf8string ) ) #define CONV_FROM_UTF8( utf8string ) ( wxConvCurrent->cMB2WC( utf8string ) )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment