Commit edf64afc authored by charras's avatar charras

Eeschema: Added patch from Torsten Huter addeing hotkeys and enhancements in libeditor

Some fixes.
parent ac97a574
...@@ -388,6 +388,41 @@ void RotatePoint( double* pX, double* pY, int angle ) ...@@ -388,6 +388,41 @@ void RotatePoint( double* pX, double* pY, int angle )
} }
double EuclideanNorm( wxPoint vector )
{
return sqrt( (double) vector.x * (double) vector.x + (double) vector.y * (double) vector.y );
}
wxPoint TwoPointVector( wxPoint startPoint, wxPoint endPoint )
{
return endPoint - startPoint;
}
double DistanceLinePoint( wxPoint linePointA, wxPoint linePointB, wxPoint referencePoint )
{
return fabs( (linePointB.x - linePointA.x) * (linePointA.y - referencePoint.y) -
(linePointA.x - referencePoint.x ) * (linePointB.y - linePointA.y) )
/ EuclideanNorm( TwoPointVector( linePointA, linePointB ) );
}
bool HitTestPoints( wxPoint pointA, wxPoint pointB, double threshold )
{
wxPoint vectorAB = TwoPointVector( pointA, pointB );
double distance = EuclideanNorm( vectorAB );
return distance < threshold;
}
int CrossProduct( wxPoint vectorA, wxPoint vectorB )
{
return vectorA.x * vectorB.y - vectorA.y * vectorB.x;
}
double fsinus[3600] = double fsinus[3600] =
{ {
0.0000000000, 0.0017453284, 0.0034906514, 0.0052359638, 0.0000000000, 0.0017453284, 0.0034906514, 0.0052359638,
......
...@@ -514,6 +514,10 @@ void SaveStructListForPaste( PICKED_ITEMS_LIST& aItemsList ) ...@@ -514,6 +514,10 @@ void SaveStructListForPaste( PICKED_ITEMS_LIST& aItemsList )
/* save the new list: */ /* save the new list: */
ITEM_PICKER item; ITEM_PICKER item;
// In list the wrapper is owner of the shematic item, we can use the UR_DELETED
// status for the picker because pickers with this status are owner of the picked item
// (or TODO ?: create a new status like UR_DUPLICATE)
item.m_UndoRedoStatus = UR_DELETED;
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ ) for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{ {
/* Make a copy of the original picked item. */ /* Make a copy of the original picked item. */
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "protos.h" #include "protos.h"
#include "classes_body_items.h" #include "classes_body_items.h"
static int fill_tab[3] = { 'N', 'F', 'f' }; static int fill_tab[3] = { 'N', 'F', 'f' };
//#define DRAW_ARC_WITH_ANGLE // Used to draw arcs //#define DRAW_ARC_WITH_ANGLE // Used to draw arcs
...@@ -231,13 +230,12 @@ bool LIB_ARC::HitTest( const wxPoint& aRefPoint ) ...@@ -231,13 +230,12 @@ bool LIB_ARC::HitTest( const wxPoint& aRefPoint )
int mindist = m_Width ? m_Width / 2 : g_DrawDefaultLineThickness / 2; int mindist = m_Width ? m_Width / 2 : g_DrawDefaultLineThickness / 2;
// Have a minimal tolerance for hit test // Have a minimal tolerance for hit test
if( mindist < 3 ) if( mindist < MINIMUM_SELECTION_DISTANCE )
mindist = 3; // = 3 mils mindist = MINIMUM_SELECTION_DISTANCE;
return HitTest( aRefPoint, mindist, DefaultTransformMatrix ); return HitTest( aRefPoint, mindist, DefaultTransformMatrix );
} }
/** Function HitTest /** Function HitTest
* @return true if the point aPosRef is near this object * @return true if the point aPosRef is near this object
* @param aRefPoint = a wxPoint to test * @param aRefPoint = a wxPoint to test
...@@ -245,38 +243,45 @@ bool LIB_ARC::HitTest( const wxPoint& aRefPoint ) ...@@ -245,38 +243,45 @@ 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 aRefPoint, int aThreshold, bool LIB_ARC::HitTest( wxPoint aReferencePoint, int aThreshold,
const int aTransMat[2][2] ) const int aTransformationMatrix[2][2] )
{ {
// TODO: use aTransMat to calculmates parameters // TODO: use aTransMat to calculmates parameters
wxPoint relpos = aRefPoint; wxPoint relativePosition = aReferencePoint;
NEGATE( relpos.y ); // reverse Y axis NEGATE( relativePosition.y ); // reverse Y axis
relpos -= m_Pos; int distance = wxRound( EuclideanNorm(TwoPointVector(m_Pos, relativePosition) ) );
int dist = wxRound( sqrt( ( (double) relpos.x * (double) relpos.x ) +
( (double) relpos.y * (double) relpos.y ) ) );
if( abs( dist - m_Radius ) > aThreshold ) if( abs( distance - m_Radius ) > aThreshold )
return false; return false;
// We are on the circle, ensure we are only on the arc, i.e. between // We are on the circle, ensure we are only on the arc, i.e. between
// m_ArcStart and m_ArcEnd // m_ArcStart and m_ArcEnd
int astart = m_t1; // arc starting point ( in 0.1 degree)
int aend = m_t2; // arc ending point ( in 0.1 degree)
int atest = wxRound( atan2( (double) relpos.y,
(double) relpos.x ) * 1800.0 / M_PI );
NORMALIZE_ANGLE_180( atest );
NORMALIZE_ANGLE_180( astart );
NORMALIZE_ANGLE_180( aend );
if( astart > aend )
EXCHG( astart, aend );
if( atest >= astart && atest <= aend )
return true;
return false; wxPoint startEndVector = TwoPointVector( m_ArcStart, m_ArcEnd);
wxPoint startRelativePositionVector = TwoPointVector( m_ArcStart, relativePosition);
wxPoint centerStartVector = TwoPointVector( m_Pos, m_ArcStart);
wxPoint centerEndVector = TwoPointVector( m_Pos, m_ArcEnd);
wxPoint centerRelativePositionVector = TwoPointVector( m_Pos, relativePosition);
// Compute the cross product to check if the point is in the sector
int crossProductStart = CrossProduct(centerStartVector, centerRelativePositionVector);
int crossProductEnd = CrossProduct(centerEndVector, centerRelativePositionVector);
// The cross products need to be exchanged, depending on which side the center point
// relative to the start point to end point vector lies
if (CrossProduct(startEndVector, startRelativePositionVector) < 0 ){
EXCHG(crossProductStart, crossProductEnd);
}
// When the cross products have a different sign, the point lies in sector
// also check, if the reference is near start or end point
return HitTestPoints(m_ArcStart, relativePosition, MINIMUM_SELECTION_DISTANCE) ||
HitTestPoints(m_ArcEnd, relativePosition, MINIMUM_SELECTION_DISTANCE) ||
(crossProductStart <= 0 && crossProductEnd >= 0);
} }
...@@ -603,8 +608,8 @@ bool LIB_CIRCLE::HitTest( const wxPoint& aPosRef ) ...@@ -603,8 +608,8 @@ bool LIB_CIRCLE::HitTest( const wxPoint& aPosRef )
int mindist = m_Width ? m_Width / 2 : g_DrawDefaultLineThickness / 2; int mindist = m_Width ? m_Width / 2 : g_DrawDefaultLineThickness / 2;
// Have a minimal tolerance for hit test // Have a minimal tolerance for hit test
if( mindist < 3 ) if( mindist < MINIMUM_SELECTION_DISTANCE )
mindist = 3; // = 3 mils mindist = MINIMUM_SELECTION_DISTANCE;
return HitTest( aPosRef, mindist, DefaultTransformMatrix ); return HitTest( aPosRef, mindist, DefaultTransformMatrix );
} }
...@@ -811,6 +816,9 @@ LIB_RECTANGLE::LIB_RECTANGLE( LIB_COMPONENT* aParent ) : ...@@ -811,6 +816,9 @@ LIB_RECTANGLE::LIB_RECTANGLE( LIB_COMPONENT* aParent ) :
m_Fill = NO_FILL; m_Fill = NO_FILL;
m_isFillable = true; m_isFillable = true;
m_typeName = _( "Rectangle" ); m_typeName = _( "Rectangle" );
m_isHeightLocked = false;
m_isWidthLocked = false;
m_isStartPointSelected = false;
} }
...@@ -1037,8 +1045,8 @@ bool LIB_RECTANGLE::HitTest( const wxPoint& aRefPoint ) ...@@ -1037,8 +1045,8 @@ bool LIB_RECTANGLE::HitTest( const wxPoint& aRefPoint )
int mindist = (m_Width ? m_Width / 2 : g_DrawDefaultLineThickness / 2) + 1; int mindist = (m_Width ? m_Width / 2 : g_DrawDefaultLineThickness / 2) + 1;
// Have a minimal tolerance for hit test // Have a minimal tolerance for hit test
if( mindist < 3 ) if( mindist < MINIMUM_SELECTION_DISTANCE )
mindist = 3; // = 3 mils mindist = MINIMUM_SELECTION_DISTANCE;
return HitTest( aRefPoint, mindist, DefaultTransformMatrix ); return HitTest( aRefPoint, mindist, DefaultTransformMatrix );
} }
...@@ -1079,8 +1087,9 @@ bool LIB_RECTANGLE::HitTest( wxPoint aRefPoint, int aThreshold, ...@@ -1079,8 +1087,9 @@ bool LIB_RECTANGLE::HitTest( wxPoint aRefPoint, int aThreshold,
return true; return true;
// locate left segment // locate left segment
start.x = actualStart.x; start = actualStart;
end.x = actualStart.y; end.x = actualStart.x;
end.y = actualEnd.y;
if( TestSegmentHit( aRefPoint, start, end, aThreshold ) ) if( TestSegmentHit( aRefPoint, start, end, aThreshold ) )
return true; return true;
...@@ -1282,8 +1291,8 @@ bool LIB_SEGMENT::HitTest( const wxPoint& aPosRef ) ...@@ -1282,8 +1291,8 @@ bool LIB_SEGMENT::HitTest( const wxPoint& aPosRef )
int mindist = m_Width ? m_Width / 2 : g_DrawDefaultLineThickness / 2; int mindist = m_Width ? m_Width / 2 : g_DrawDefaultLineThickness / 2;
// Have a minimal tolerance for hit test // Have a minimal tolerance for hit test
if( mindist < 3 ) if( mindist < MINIMUM_SELECTION_DISTANCE )
mindist = 3; // = 3 mils mindist = MINIMUM_SELECTION_DISTANCE;
return HitTest( aPosRef, mindist, DefaultTransformMatrix ); return HitTest( aPosRef, mindist, DefaultTransformMatrix );
} }
...@@ -1613,8 +1622,8 @@ bool LIB_POLYLINE::HitTest( const wxPoint& aRefPos ) ...@@ -1613,8 +1622,8 @@ bool LIB_POLYLINE::HitTest( const wxPoint& aRefPos )
int mindist = m_Width ? m_Width / 2 : g_DrawDefaultLineThickness / 2; int mindist = m_Width ? m_Width / 2 : g_DrawDefaultLineThickness / 2;
// Have a minimal tolerance for hit test // Have a minimal tolerance for hit test
if( mindist < 3 ) if( mindist < MINIMUM_SELECTION_DISTANCE )
mindist = 3; // = 3 mils mindist = MINIMUM_SELECTION_DISTANCE;
return HitTest( aRefPos, mindist, DefaultTransformMatrix ); return HitTest( aRefPos, mindist, DefaultTransformMatrix );
} }
...@@ -1980,8 +1989,8 @@ bool LIB_BEZIER::HitTest( const wxPoint& aRefPos ) ...@@ -1980,8 +1989,8 @@ bool LIB_BEZIER::HitTest( const wxPoint& aRefPos )
{ {
int mindist = m_Width ? m_Width /2 : g_DrawDefaultLineThickness / 2; int mindist = m_Width ? m_Width /2 : g_DrawDefaultLineThickness / 2;
// Have a minimal tolerance for hit test // Have a minimal tolerance for hit test
if ( mindist < 3 ) if ( mindist < MINIMUM_SELECTION_DISTANCE )
mindist = 3; // = 3 mils mindist = MINIMUM_SELECTION_DISTANCE;
return HitTest( aRefPos, mindist, DefaultTransformMatrix ); return HitTest( aRefPos, mindist, DefaultTransformMatrix );
} }
......
...@@ -32,7 +32,7 @@ class LIB_PIN; ...@@ -32,7 +32,7 @@ class LIB_PIN;
#define CLOCK_PIN_DIM 40 /* Dim of clock pin symbol. */ #define CLOCK_PIN_DIM 40 /* Dim of clock pin symbol. */
#define IEEE_SYMBOL_PIN_DIM 40 /* Dim of special pin symbol. */ #define IEEE_SYMBOL_PIN_DIM 40 /* Dim of special pin symbol. */
#define MINIMUM_SELECTION_DISTANCE 15 // Minimum selection distance in mils
/** /**
* The component library pin object electrical types used in ERC tests. * The component library pin object electrical types used in ERC tests.
...@@ -978,6 +978,9 @@ public: ...@@ -978,6 +978,9 @@ 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. */
int m_Width; /* Line width */ int m_Width; /* Line width */
bool m_isWidthLocked; /* Flag: Keep width locked */
bool m_isHeightLocked; /* Flag: Keep height locked */
bool m_isStartPointSelected; /* Flag: is the upper left edge selected ? */
public: public:
LIB_RECTANGLE(LIB_COMPONENT * aParent); LIB_RECTANGLE(LIB_COMPONENT * aParent);
...@@ -1146,6 +1149,7 @@ class LIB_POLYLINE : public LIB_DRAW_ITEM ...@@ -1146,6 +1149,7 @@ class LIB_POLYLINE : public LIB_DRAW_ITEM
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
public: public:
LIB_POLYLINE(LIB_COMPONENT * aParent); LIB_POLYLINE(LIB_COMPONENT * aParent);
......
...@@ -166,6 +166,7 @@ enum id_eeschema_frm ...@@ -166,6 +166,7 @@ enum id_eeschema_frm
ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNUMSIZE_ITEM, ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNUMSIZE_ITEM,
ID_POPUP_LIBEDIT_BODY_EDIT_ITEM, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM,
ID_POPUP_LIBEDIT_DELETE_ITEM, ID_POPUP_LIBEDIT_DELETE_ITEM,
ID_POPUP_LIBEDIT_MODIFY_ITEM,
ID_POPUP_LIBEDIT_END_CREATE_ITEM, ID_POPUP_LIBEDIT_END_CREATE_ITEM,
ID_POPUP_LIBEDIT_CANCEL_EDITING, ID_POPUP_LIBEDIT_CANCEL_EDITING,
ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST,
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
* added both in eeschema and libedit) * added both in eeschema and libedit)
* Add the new code in the switch in OnHotKey() function. * Add the new code in the switch in OnHotKey() function.
* when the variable ItemInEdit is true, an item is currently edited. * when the variable ItemInEdit is true, an item is currently edited.
* This can be usefull if the new function cannot be executed while an item is * This can be useful if the new function cannot be executed while an item is
* currently being edited * currently being edited
* ( For example, one cannot start a new wire when a component is moving.) * ( For example, one cannot start a new wire when a component is moving.)
* *
...@@ -62,16 +62,16 @@ static Ki_HotkeyInfo HkZoomRedraw( wxT( "Zoom Redraw" ), HK_ZOOM_REDRAW, ...@@ -62,16 +62,16 @@ static Ki_HotkeyInfo HkZoomRedraw( wxT( "Zoom Redraw" ), HK_ZOOM_REDRAW,
/* Zoom In */ /* Zoom In */
#if !defined( __WXMAC__ ) #if !defined( __WXMAC__ )
static Ki_HotkeyInfo HkZoomIn( wxT( "Zoom In" ), HK_ZOOM_IN, WXK_F1 ); static Ki_HotkeyInfo HkZoomIn( wxT( "Zoom In" ), HK_ZOOM_IN, WXK_F1 );
#else #else
static Ki_HotkeyInfo HkZoomIn( wxT( "Zoom In" ), HK_ZOOM_IN, GR_KB_CTRL + '+' ); static Ki_HotkeyInfo HkZoomIn( wxT( "Zoom In" ), HK_ZOOM_IN, GR_KB_CTRL + '+' );
#endif #endif
/* Zoom Out */ /* Zoom Out */
#if !defined( __WXMAC__ ) #if !defined( __WXMAC__ )
static Ki_HotkeyInfo HkZoomOut( wxT( "Zoom Out" ), HK_ZOOM_OUT, WXK_F2 ); static Ki_HotkeyInfo HkZoomOut( wxT( "Zoom Out" ), HK_ZOOM_OUT, WXK_F2 );
#else #else
static Ki_HotkeyInfo HkZoomOut( wxT( "Zoom Out" ), HK_ZOOM_OUT, GR_KB_CTRL + '-' ); static Ki_HotkeyInfo HkZoomOut( wxT( "Zoom Out" ), HK_ZOOM_OUT, GR_KB_CTRL + '-' );
#endif #endif
static Ki_HotkeyInfo HkHelp( wxT( "Help: this message" ), HK_HELP, '?' ); static Ki_HotkeyInfo HkHelp( wxT( "Help: this message" ), HK_HELP, '?' );
...@@ -84,10 +84,10 @@ static Ki_HotkeyInfo HkUndo( wxT( "Undo" ), HK_UNDO, GR_KB_CTRL + 'Z', ...@@ -84,10 +84,10 @@ static Ki_HotkeyInfo HkUndo( wxT( "Undo" ), HK_UNDO, GR_KB_CTRL + 'Z',
/* 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) ID_SCHEMATIC_REDO ); (int) ID_SCHEMATIC_REDO );
#endif #endif
...@@ -102,16 +102,16 @@ static Ki_HotkeyInfo HkMirrorXComponent( wxT( "Mirror X Component" ), ...@@ -102,16 +102,16 @@ static Ki_HotkeyInfo HkMirrorXComponent( wxT( "Mirror X Component" ),
HK_MIRROR_X_COMPONENT, 'X' ); HK_MIRROR_X_COMPONENT, 'X' );
static Ki_HotkeyInfo HkOrientNormalComponent( wxT( "Orient Normal Component" ), static Ki_HotkeyInfo HkOrientNormalComponent( wxT( "Orient Normal Component" ),
HK_ORIENT_NORMAL_COMPONENT, 'N' ); HK_ORIENT_NORMAL_COMPONENT, 'N' );
static Ki_HotkeyInfo HkRotateComponentOrItem( wxT( "Rotate Schematic Item" ), static Ki_HotkeyInfo HkRotate( wxT( "Rotate Schematic Item" ),
HK_ROTATE_COMPONENT_OR_ITEM, 'R' ); HK_ROTATE, 'R' );
static Ki_HotkeyInfo HkEditComponent( wxT( "Edit Component or Label" ), static Ki_HotkeyInfo HkEdit( wxT( "Edit Schematic Item" ),
HK_EDIT_COMPONENT_OR_LABEL, 'E' ); HK_EDIT, 'E' );
static Ki_HotkeyInfo HkEditComponentValue( wxT( "Edit Component Value" ), static Ki_HotkeyInfo HkEditComponentValue( wxT( "Edit Component Value" ),
HK_EDIT_COMPONENT_VALUE, 'V' ); HK_EDIT_COMPONENT_VALUE, 'V' );
static Ki_HotkeyInfo HkEditComponentFootprint( wxT( "Edit Component Footprint" ), static Ki_HotkeyInfo HkEditComponentFootprint( wxT( "Edit Component Footprint" ),
HK_EDIT_COMPONENT_FOOTPRINT, HK_EDIT_COMPONENT_FOOTPRINT,
'F' ); 'F' );
static Ki_HotkeyInfo HkMoveComponentOrItem( wxT( "Move Schematic Item" ), static Ki_HotkeyInfo HkMove( wxT( "Move Schematic Item" ),
HK_MOVE_COMPONENT_OR_ITEM, 'M', HK_MOVE_COMPONENT_OR_ITEM, 'M',
ID_POPUP_SCH_MOVE_CMP_REQUEST ); ID_POPUP_SCH_MOVE_CMP_REQUEST );
...@@ -119,8 +119,8 @@ static Ki_HotkeyInfo HkCopyComponentOrText( wxT( "Copy Component or Label" ), ...@@ -119,8 +119,8 @@ 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 HkDragComponent( wxT( "Drag Component" ), static Ki_HotkeyInfo HkDrag( wxT( "Drag Schematic Item" ),
HK_DRAG_COMPONENT, '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' );
...@@ -130,12 +130,10 @@ static Ki_HotkeyInfo HkDelete( wxT( "Delete Item" ), HK_DELETE, WXK_DELETE ); ...@@ -130,12 +130,10 @@ static Ki_HotkeyInfo HkDelete( wxT( "Delete Item" ), HK_DELETE, WXK_DELETE );
static Ki_HotkeyInfo HkNextSearch( wxT( "Next Search" ), HK_NEXT_SEARCH, static Ki_HotkeyInfo HkNextSearch( wxT( "Next Search" ), HK_NEXT_SEARCH,
WXK_F5 ); WXK_F5 );
// Library editor: // Special keys for library editor:
static Ki_HotkeyInfo HkInsertPin( wxT( "Repeat Pin" ), HK_REPEAT_LAST, static Ki_HotkeyInfo HkInsertPin( wxT( "Repeat Pin" ), HK_REPEAT_LAST,
WXK_INSERT ); WXK_INSERT );
static Ki_HotkeyInfo HkEditPin( wxT( "Edit Pin" ), HK_EDIT_PIN, 'E' );
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' );
static Ki_HotkeyInfo HkRotatePin( wxT( "Rotate Pin" ), HK_LIBEDIT_ROTATE_PIN, 'R' );
static Ki_HotkeyInfo HkDeletePin( wxT( "Delete Pin" ), HK_DELETE_PIN, static Ki_HotkeyInfo HkDeletePin( wxT( "Delete Pin" ), HK_DELETE_PIN,
WXK_DELETE ); WXK_DELETE );
...@@ -144,10 +142,14 @@ static Ki_HotkeyInfo HkDeletePin( wxT( "Delete Pin" ), HK_DELETE_PIN, ...@@ -144,10 +142,14 @@ static Ki_HotkeyInfo HkDeletePin( wxT( "Delete Pin" ), HK_DELETE_PIN,
Ki_HotkeyInfo* s_Common_Hotkey_List[] = Ki_HotkeyInfo* s_Common_Hotkey_List[] =
{ {
&HkHelp, &HkHelp,
&HkZoomIn, &HkZoomOut, &HkZoomRedraw, &HkZoomIn,
&HkZoomCenter, &HkZoomAuto, &HkZoomOut,
&HkZoomRedraw,
&HkZoomCenter,
&HkZoomAuto,
&HkResetLocalCoord, &HkResetLocalCoord,
&HkUndo, &HkRedo, &HkUndo,
&HkRedo,
NULL NULL
}; };
...@@ -155,12 +157,20 @@ Ki_HotkeyInfo* s_Common_Hotkey_List[] = ...@@ -155,12 +157,20 @@ Ki_HotkeyInfo* s_Common_Hotkey_List[] =
Ki_HotkeyInfo* s_Schematic_Hotkey_List[] = Ki_HotkeyInfo* s_Schematic_Hotkey_List[] =
{ {
&HkNextSearch, &HkNextSearch,
&HkDelete, &HkInsert, &HkMove2Drag, &HkDelete,
&HkMoveComponentOrItem, &HkCopyComponentOrText, &HkInsert,
&HkDragComponent, &HkAddComponent, &HkMove2Drag,
&HkRotateComponentOrItem, &HkMirrorXComponent, &HkMirrorYComponent, &HkMove,
&HkCopyComponentOrText,
&HkDrag,
&HkAddComponent,
&HkRotate,
&HkMirrorXComponent,
&HkMirrorYComponent,
&HkOrientNormalComponent, &HkOrientNormalComponent,
&HkEditComponent,&HkEditComponentValue,&HkEditComponentFootprint, &HkEdit,
&HkEditComponentValue,
&HkEditComponentFootprint,
&HkBeginWire, &HkBeginWire,
NULL NULL
}; };
...@@ -169,10 +179,11 @@ Ki_HotkeyInfo* s_Schematic_Hotkey_List[] = ...@@ -169,10 +179,11 @@ Ki_HotkeyInfo* s_Schematic_Hotkey_List[] =
Ki_HotkeyInfo* s_LibEdit_Hotkey_List[] = Ki_HotkeyInfo* s_LibEdit_Hotkey_List[] =
{ {
&HkInsertPin, &HkInsertPin,
&HkEditPin, &HkEdit,
&HkMovePin, &HkMovePin,
&HkDeletePin, &HkDeletePin,
&HkRotatePin, &HkRotate,
&HkDrag,
NULL NULL
}; };
...@@ -336,6 +347,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -336,6 +347,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
break; break;
case HK_BEGIN_WIRE: case HK_BEGIN_WIRE:
/* An item is selected. If edited and not a wire, a new command is not /* An item is selected. If edited and not a wire, a new command is not
* possible */ * possible */
if( !ItemInEdit && screen->m_BlockLocate.m_State == STATE_NO_BLOCK ) if( !ItemInEdit && screen->m_BlockLocate.m_State == STATE_NO_BLOCK )
...@@ -359,7 +371,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -359,7 +371,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
} }
break; break;
case HK_ROTATE_COMPONENT_OR_ITEM: // Component or other schematic item rotation case HK_ROTATE: // Component or other schematic item rotation
if( DrawStruct == NULL ) if( DrawStruct == NULL )
{ {
...@@ -376,16 +388,16 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -376,16 +388,16 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
break; break;
} }
if (DrawStruct) if( DrawStruct )
{ {
GetScreen()->SetCurItem( (SCH_ITEM*) DrawStruct ); GetScreen()->SetCurItem( (SCH_ITEM*) DrawStruct );
// Create the events for rotating a component or other schematic item // Create the events for rotating a component or other schematic item
wxCommandEvent eventRotateComponent( wxEVT_COMMAND_TOOL_CLICKED, wxCommandEvent eventRotateComponent( wxEVT_COMMAND_TOOL_CLICKED,
ID_POPUP_SCH_ROTATE_CMP_COUNTERCLOCKWISE ); ID_POPUP_SCH_ROTATE_CMP_COUNTERCLOCKWISE );
wxCommandEvent eventRotateText(wxEVT_COMMAND_TOOL_CLICKED, wxCommandEvent eventRotateText( wxEVT_COMMAND_TOOL_CLICKED,
ID_POPUP_SCH_ROTATE_TEXT ); ID_POPUP_SCH_ROTATE_TEXT );
wxCommandEvent eventRotateField(wxEVT_COMMAND_TOOL_CLICKED, wxCommandEvent eventRotateField( wxEVT_COMMAND_TOOL_CLICKED,
ID_POPUP_SCH_ROTATE_FIELD ); ID_POPUP_SCH_ROTATE_FIELD );
switch( DrawStruct->Type() ) switch( DrawStruct->Type() )
...@@ -400,6 +412,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -400,6 +412,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
case TYPE_SCH_HIERLABEL: case TYPE_SCH_HIERLABEL:
wxPostEvent( this, eventRotateText ); wxPostEvent( this, eventRotateText );
break; break;
case DRAW_PART_TEXT_STRUCT_TYPE: case DRAW_PART_TEXT_STRUCT_TYPE:
wxPostEvent( this, eventRotateField ); wxPostEvent( this, eventRotateField );
...@@ -453,7 +466,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -453,7 +466,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
} }
break; break;
case HK_DRAG_COMPONENT: // Start drag component case HK_DRAG: // Start drag
case HK_MOVE_COMPONENT_OR_ITEM: // Start move component or other schematic item case HK_MOVE_COMPONENT_OR_ITEM: // Start move component or other schematic item
case HK_COPY_COMPONENT_OR_LABEL: // Duplicate component or text/label case HK_COPY_COMPONENT_OR_LABEL: // Duplicate component or text/label
if( ItemInEdit ) if( ItemInEdit )
...@@ -470,16 +483,18 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -470,16 +483,18 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
DrawStruct = LocateSmallestComponent( GetScreen() ); DrawStruct = LocateSmallestComponent( GetScreen() );
if( DrawStruct == NULL ) if( DrawStruct == NULL )
break; break;
if( DrawStruct->Type() == DRAW_SHEET_STRUCT_TYPE ){ if( DrawStruct->Type() == DRAW_SHEET_STRUCT_TYPE )
{
// 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;
} }
if (DrawStruct->Type() == DRAW_JUNCTION_STRUCT_TYPE){ if( DrawStruct->Type() == DRAW_JUNCTION_STRUCT_TYPE )
{
// If it's a junction, pick the underlying wire instead // If it's a junction, pick the underlying wire instead
DrawStruct = PickStruct( GetScreen()->m_Curseur, GetScreen(), WIREITEM); DrawStruct = PickStruct( GetScreen()->m_Curseur, GetScreen(), WIREITEM );
} }
if( DrawStruct == NULL ) if( DrawStruct == NULL )
break; break;
...@@ -494,22 +509,22 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -494,22 +509,22 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
break; break;
} }
if( DrawStruct && (DrawStruct->m_Flags == 0) ){ if( DrawStruct && (DrawStruct->m_Flags == 0) )
{
GetScreen()->SetCurItem( (SCH_ITEM*) DrawStruct ); GetScreen()->SetCurItem( (SCH_ITEM*) DrawStruct );
// Create the events for moving a component or other schematic item // Create the events for moving a component or other schematic item
wxCommandEvent eventMoveComponent( wxEVT_COMMAND_TOOL_CLICKED, wxCommandEvent eventMoveComponent( wxEVT_COMMAND_TOOL_CLICKED,
HK_Descr->m_IdMenuEvent ); HK_Descr->m_IdMenuEvent );
wxCommandEvent eventMoveItem(wxEVT_COMMAND_TOOL_CLICKED, wxCommandEvent eventMoveItem( wxEVT_COMMAND_TOOL_CLICKED,
ID_POPUP_SCH_MOVE_ITEM_REQUEST ); ID_POPUP_SCH_MOVE_ITEM_REQUEST );
wxCommandEvent eventMovePinsheet(wxEVT_COMMAND_TOOL_CLICKED, wxCommandEvent eventMovePinsheet( wxEVT_COMMAND_TOOL_CLICKED,
ID_POPUP_SCH_MOVE_PINSHEET); ID_POPUP_SCH_MOVE_PINSHEET );
wxCommandEvent eventDragWire(wxEVT_COMMAND_TOOL_CLICKED, wxCommandEvent eventDragWire( wxEVT_COMMAND_TOOL_CLICKED,
ID_POPUP_SCH_DRAG_WIRE_REQUEST); ID_POPUP_SCH_DRAG_WIRE_REQUEST );
switch( DrawStruct->Type() ) switch( DrawStruct->Type() )
{ {
// select the correct event for moving an schematic object // select the correct event for moving an schematic object
// and add it to the event queue // and add it to the event queue
case TYPE_SCH_COMPONENT: case TYPE_SCH_COMPONENT:
...@@ -531,7 +546,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -531,7 +546,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
break; break;
case DRAW_SEGMENT_STRUCT_TYPE: case DRAW_SEGMENT_STRUCT_TYPE:
if (((SCH_ITEM*)DrawStruct)->GetLayer() == LAYER_WIRE) if( ( (SCH_ITEM*) DrawStruct )->GetLayer() == LAYER_WIRE )
wxPostEvent( this, eventDragWire ); wxPostEvent( this, eventDragWire );
break; break;
...@@ -542,7 +557,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -542,7 +557,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
break; break;
case HK_EDIT_COMPONENT_OR_LABEL: case HK_EDIT:
if( ItemInEdit ) if( ItemInEdit )
break; break;
...@@ -561,13 +576,13 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -561,13 +576,13 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
if( DrawStruct ) if( DrawStruct )
{ {
wxCommandEvent eventEditPinsheet( wxEVT_COMMAND_TOOL_CLICKED,
ID_POPUP_SCH_EDIT_SHEET );
wxCommandEvent eventEditPinsheet(wxEVT_COMMAND_TOOL_CLICKED,
ID_POPUP_SCH_EDIT_SHEET);
switch( DrawStruct->Type() ) switch( DrawStruct->Type() )
{ {
case TYPE_SCH_COMPONENT: case TYPE_SCH_COMPONENT:
InstallCmpeditFrame( this, MousePos,(SCH_COMPONENT*) DrawStruct ); InstallCmpeditFrame( this, MousePos, (SCH_COMPONENT*) DrawStruct );
break; break;
case DRAW_SHEET_STRUCT_TYPE: case DRAW_SHEET_STRUCT_TYPE:
...@@ -713,26 +728,54 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -713,26 +728,54 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey,
wxBell(); wxBell();
break; break;
case HK_EDIT_PIN: case HK_EDIT:
m_drawItem = LocateItemUsingCursor(); m_drawItem = LocateItemUsingCursor();
if( m_drawItem && m_drawItem->Type() == COMPONENT_PIN_DRAW_TYPE ) if( m_drawItem )
{ {
switch( m_drawItem->Type() )
{
case COMPONENT_PIN_DRAW_TYPE:
cmd.SetId( ID_LIBEDIT_EDIT_PIN ); cmd.SetId( ID_LIBEDIT_EDIT_PIN );
GetEventHandler()->ProcessEvent( cmd ); GetEventHandler()->ProcessEvent( cmd );
} break;
case COMPONENT_ARC_DRAW_TYPE:
case COMPONENT_CIRCLE_DRAW_TYPE:
case COMPONENT_RECT_DRAW_TYPE:
case COMPONENT_POLYLINE_DRAW_TYPE:
case COMPONENT_GRAPHIC_TEXT_DRAW_TYPE:
cmd.SetId( ID_POPUP_LIBEDIT_BODY_EDIT_ITEM );
GetEventHandler()->ProcessEvent( cmd );
break; break;
case HK_LIBEDIT_ROTATE_PIN: default:
break;
}
}
break;
case HK_ROTATE:
m_drawItem = LocateItemUsingCursor(); m_drawItem = LocateItemUsingCursor();
if( m_drawItem && m_drawItem->Type() == COMPONENT_PIN_DRAW_TYPE ) if( m_drawItem )
{ {
switch( m_drawItem->Type() )
{
case COMPONENT_PIN_DRAW_TYPE:
cmd.SetId( ID_LIBEDIT_ROTATE_PIN ); cmd.SetId( ID_LIBEDIT_ROTATE_PIN );
GetEventHandler()->ProcessEvent( cmd ); GetEventHandler()->ProcessEvent( cmd );
} break;
case COMPONENT_GRAPHIC_TEXT_DRAW_TYPE:
cmd.SetId( ID_POPUP_LIBEDIT_ROTATE_GRAPHIC_TEXT );
GetEventHandler()->ProcessEvent( cmd );
break;
default:
break;
}
}
break; break;
...@@ -757,5 +800,16 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey, ...@@ -757,5 +800,16 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey,
Process_Special_Functions( evt ); Process_Special_Functions( evt );
} }
break; break;
case HK_DRAG:
m_drawItem = LocateItemUsingCursor();
if( m_drawItem )
{
wxCommandEvent evt;
evt.SetId( ID_POPUP_LIBEDIT_MODIFY_ITEM );
Process_Special_Functions( evt );
}
break;
} }
} }
...@@ -25,8 +25,8 @@ enum hotkey_id_commnand { ...@@ -25,8 +25,8 @@ enum hotkey_id_commnand {
HK_UNDO, HK_UNDO,
HK_REDO, HK_REDO,
HK_MOVEBLOCK_TO_DRAGBLOCK, HK_MOVEBLOCK_TO_DRAGBLOCK,
HK_ROTATE_COMPONENT_OR_ITEM, HK_ROTATE,
HK_EDIT_COMPONENT_OR_LABEL, HK_EDIT,
HK_EDIT_COMPONENT_VALUE, HK_EDIT_COMPONENT_VALUE,
HK_EDIT_COMPONENT_FOOTPRINT, HK_EDIT_COMPONENT_FOOTPRINT,
HK_MIRROR_X_COMPONENT, HK_MIRROR_X_COMPONENT,
...@@ -34,7 +34,7 @@ enum hotkey_id_commnand { ...@@ -34,7 +34,7 @@ enum hotkey_id_commnand {
HK_ORIENT_NORMAL_COMPONENT, HK_ORIENT_NORMAL_COMPONENT,
HK_MOVE_COMPONENT_OR_ITEM, HK_MOVE_COMPONENT_OR_ITEM,
HK_COPY_COMPONENT_OR_LABEL, HK_COPY_COMPONENT_OR_LABEL,
HK_DRAG_COMPONENT, HK_DRAG,
HK_ADD_NEW_COMPONENT, HK_ADD_NEW_COMPONENT,
HK_BEGIN_WIRE HK_BEGIN_WIRE
}; };
......
...@@ -30,6 +30,8 @@ void WinEDA_LibeditFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos ) ...@@ -30,6 +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 ); SaveCopyInUndoList( m_component );
switch( DrawEntry->Type() ) switch( DrawEntry->Type() )
......
...@@ -84,9 +84,17 @@ bool WinEDA_LibeditFrame::OnRightClick( const wxPoint& MousePos, ...@@ -84,9 +84,17 @@ bool WinEDA_LibeditFrame::OnRightClick( const wxPoint& MousePos,
HK_LIBEDIT_MOVE_GRAPHIC_ITEM ); HK_LIBEDIT_MOVE_GRAPHIC_ITEM );
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST, ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST,
msg, move_arc_xpm ); msg, move_arc_xpm );
msg = AddHotkeyName( _( "Drag Arc Size" ), s_Libedit_Hokeys_Descr,
HK_DRAG );
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MODIFY_ITEM,
msg, move_arc_xpm );
} }
msg = AddHotkeyName( _( "Edit Arc Options" ), s_Libedit_Hokeys_Descr,
HK_EDIT );
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM, ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM,
_( "Arc Options" ), options_arc_xpm ); msg, options_arc_xpm );
if( DrawEntry->m_Flags == 0 ) if( DrawEntry->m_Flags == 0 )
{ {
msg = AddHotkeyName( _( "Delete Arc " ), s_Libedit_Hokeys_Descr, msg = AddHotkeyName( _( "Delete Arc " ), s_Libedit_Hokeys_Descr,
...@@ -104,8 +112,20 @@ bool WinEDA_LibeditFrame::OnRightClick( const wxPoint& MousePos, ...@@ -104,8 +112,20 @@ bool WinEDA_LibeditFrame::OnRightClick( const wxPoint& MousePos,
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST, ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST,
msg, move_circle_xpm ); msg, move_circle_xpm );
} }
if( DrawEntry->m_Flags == 0 )
{
msg = AddHotkeyName( _( "Drag Circle Outline" ), s_Libedit_Hokeys_Descr,
HK_DRAG );
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MODIFY_ITEM,
msg, move_rectangle_xpm );
}
msg = AddHotkeyName( _( "Edit Circle Options" ), s_Libedit_Hokeys_Descr,
HK_EDIT );
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM, ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM,
_( "Circle Options" ), options_circle_xpm ); msg, options_circle_xpm );
if( DrawEntry->m_Flags == 0 ) if( DrawEntry->m_Flags == 0 )
{ {
msg = AddHotkeyName( _( "Delete Circle " ), msg = AddHotkeyName( _( "Delete Circle " ),
...@@ -118,20 +138,33 @@ bool WinEDA_LibeditFrame::OnRightClick( const wxPoint& MousePos, ...@@ -118,20 +138,33 @@ bool WinEDA_LibeditFrame::OnRightClick( const wxPoint& MousePos,
case COMPONENT_RECT_DRAW_TYPE: case COMPONENT_RECT_DRAW_TYPE:
if( DrawEntry->m_Flags == 0 ) if( DrawEntry->m_Flags == 0 )
{ {
msg = AddHotkeyName( _( "Move Rect " ), s_Libedit_Hokeys_Descr, msg = AddHotkeyName( _( "Move Rectangle " ), s_Libedit_Hokeys_Descr,
HK_LIBEDIT_MOVE_GRAPHIC_ITEM ); HK_LIBEDIT_MOVE_GRAPHIC_ITEM );
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST, ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST,
msg, move_rectangle_xpm ); msg, move_rectangle_xpm );
} }
msg = AddHotkeyName( _( "Edit Rectangle Options" ), s_Libedit_Hokeys_Descr,
HK_EDIT );
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM, ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM,
_( "Rect Options" ), options_rectangle_xpm ); msg, options_rectangle_xpm );
if( DrawEntry->m_Flags == 0 )
{
msg = AddHotkeyName( _( "Drag Rectangle Edge" ), s_Libedit_Hokeys_Descr,
HK_DRAG );
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MODIFY_ITEM,
msg, move_rectangle_xpm );
}
if( DrawEntry->m_Flags == 0 ) if( DrawEntry->m_Flags == 0 )
{ {
msg = AddHotkeyName( _( "Delete Rect " ), s_Libedit_Hokeys_Descr, msg = AddHotkeyName( _( "Delete Rectangle " ), s_Libedit_Hokeys_Descr,
HK_DELETE_PIN ); HK_DELETE_PIN );
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_DELETE_ITEM, ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_DELETE_ITEM,
msg, delete_rectangle_xpm ); msg, delete_rectangle_xpm );
} }
break; break;
case COMPONENT_GRAPHIC_TEXT_DRAW_TYPE: case COMPONENT_GRAPHIC_TEXT_DRAW_TYPE:
...@@ -142,10 +175,17 @@ bool WinEDA_LibeditFrame::OnRightClick( const wxPoint& MousePos, ...@@ -142,10 +175,17 @@ bool WinEDA_LibeditFrame::OnRightClick( const wxPoint& MousePos,
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST, ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST,
msg, move_text_xpm ); msg, move_text_xpm );
} }
msg = AddHotkeyName( _( "Edit Text " ), s_Libedit_Hokeys_Descr,
HK_EDIT );
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM, ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM,
_( "Text Editor" ), edit_text_xpm ); msg, edit_text_xpm );
msg = AddHotkeyName( _( "Rotate Text " ), s_Libedit_Hokeys_Descr,
HK_ROTATE );
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_ROTATE_GRAPHIC_TEXT, ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_ROTATE_GRAPHIC_TEXT,
_( "Rotate Text" ), edit_text_xpm ); msg, edit_text_xpm );
if( DrawEntry->m_Flags == 0 ) if( DrawEntry->m_Flags == 0 )
{ {
msg = AddHotkeyName( _( "Delete Text " ), s_Libedit_Hokeys_Descr, msg = AddHotkeyName( _( "Delete Text " ), s_Libedit_Hokeys_Descr,
...@@ -162,14 +202,23 @@ bool WinEDA_LibeditFrame::OnRightClick( const wxPoint& MousePos, ...@@ -162,14 +202,23 @@ bool WinEDA_LibeditFrame::OnRightClick( const wxPoint& MousePos,
HK_LIBEDIT_MOVE_GRAPHIC_ITEM ); HK_LIBEDIT_MOVE_GRAPHIC_ITEM );
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST, ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST,
msg, move_line_xpm ); msg, move_line_xpm );
msg = AddHotkeyName( _( "Drag Edge Point" ), s_Libedit_Hokeys_Descr,
HK_DRAG );
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_MODIFY_ITEM,
msg, move_line_xpm );
} }
if( DrawEntry->m_Flags & IS_NEW ) if( DrawEntry->m_Flags & IS_NEW )
{ {
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_END_CREATE_ITEM, ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_END_CREATE_ITEM,
_( "Line End" ), apply_xpm ); _( "Line End" ), apply_xpm );
} }
msg = AddHotkeyName( _( "Edit Line Options" ), s_Libedit_Hokeys_Descr,
HK_EDIT );
ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM, ADD_MENUITEM( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM,
_( "Line Options" ), options_segment_xpm ); msg, options_segment_xpm );
if( DrawEntry->m_Flags == 0 ) if( DrawEntry->m_Flags == 0 )
{ {
msg = AddHotkeyName( _( "Delete Line " ), s_Libedit_Hokeys_Descr, msg = AddHotkeyName( _( "Delete Line " ), s_Libedit_Hokeys_Descr,
...@@ -188,6 +237,7 @@ bool WinEDA_LibeditFrame::OnRightClick( const wxPoint& MousePos, ...@@ -188,6 +237,7 @@ bool WinEDA_LibeditFrame::OnRightClick( const wxPoint& MousePos,
msg, delete_segment_xpm ); msg, delete_segment_xpm );
} }
} }
break; break;
case COMPONENT_FIELD_DRAW_TYPE: case COMPONENT_FIELD_DRAW_TYPE:
...@@ -236,10 +286,10 @@ void AddMenusForPin( wxMenu* PopMenu, ...@@ -236,10 +286,10 @@ void AddMenusForPin( wxMenu* PopMenu,
msg, move_xpm ); msg, move_xpm );
} }
msg = AddHotkeyName( _( "Edit Pin " ), s_Libedit_Hokeys_Descr, HK_EDIT_PIN ); msg = AddHotkeyName( _( "Edit Pin " ), s_Libedit_Hokeys_Descr, HK_EDIT);
ADD_MENUITEM( PopMenu, ID_LIBEDIT_EDIT_PIN, msg, edit_xpm ); ADD_MENUITEM( PopMenu, ID_LIBEDIT_EDIT_PIN, msg, edit_xpm );
msg = AddHotkeyName( _( "Rotate Pin " ), s_Libedit_Hokeys_Descr, HK_LIBEDIT_ROTATE_PIN ); msg = AddHotkeyName( _( "Rotate Pin " ), s_Libedit_Hokeys_Descr, HK_ROTATE );
ADD_MENUITEM( PopMenu, ID_LIBEDIT_ROTATE_PIN, msg, rotate_pin_xpm ); ADD_MENUITEM( PopMenu, ID_LIBEDIT_ROTATE_PIN, msg, rotate_pin_xpm );
if( not_in_move ) if( not_in_move )
......
...@@ -172,6 +172,7 @@ private: ...@@ -172,6 +172,7 @@ private:
LIB_DRAW_ITEM* CreateGraphicItem( LIB_COMPONENT* LibEntry, wxDC* DC ); LIB_DRAW_ITEM* CreateGraphicItem( LIB_COMPONENT* LibEntry, wxDC* DC );
void GraphicItemBeginDraw( wxDC* DC ); void GraphicItemBeginDraw( wxDC* DC );
void StartMoveDrawSymbol( wxDC* DC ); void StartMoveDrawSymbol( wxDC* DC );
void StartModifyDrawSymbol( wxDC* DC ); //<! Modify the item, adjust size etc.
void EndDrawGraphicItem( wxDC* DC ); void EndDrawGraphicItem( wxDC* DC );
void LoadOneSymbol(); void LoadOneSymbol();
void SaveOneSymbol(); void SaveOneSymbol();
......
...@@ -42,114 +42,114 @@ int CreateNewLibAndSavePartId = ::wxNewId(); ...@@ -42,114 +42,114 @@ int CreateNewLibAndSavePartId = ::wxNewId();
* making it necessary to use the class access methods. * making it necessary to use the class access methods.
*/ */
LIB_COMPONENT* WinEDA_LibeditFrame::m_component = NULL; LIB_COMPONENT* WinEDA_LibeditFrame::m_component = NULL;
CMP_LIBRARY* WinEDA_LibeditFrame::m_library = NULL; CMP_LIBRARY* WinEDA_LibeditFrame:: m_library = NULL;
wxString WinEDA_LibeditFrame::m_aliasName; wxString WinEDA_LibeditFrame:: m_aliasName;
int WinEDA_LibeditFrame::m_unit = 1; int WinEDA_LibeditFrame:: m_unit = 1;
int WinEDA_LibeditFrame::m_convert = 1; int WinEDA_LibeditFrame:: m_convert = 1;
LIB_DRAW_ITEM* WinEDA_LibeditFrame::m_lastDrawItem = NULL; LIB_DRAW_ITEM* WinEDA_LibeditFrame::m_lastDrawItem = NULL;
LIB_DRAW_ITEM* WinEDA_LibeditFrame::m_drawItem = NULL; LIB_DRAW_ITEM* WinEDA_LibeditFrame::m_drawItem = NULL;
bool WinEDA_LibeditFrame::m_showDeMorgan = false; bool WinEDA_LibeditFrame:: m_showDeMorgan = false;
wxSize WinEDA_LibeditFrame::m_clientSize = wxSize( -1, -1 ); wxSize WinEDA_LibeditFrame:: m_clientSize = wxSize( -1, -1 );
int WinEDA_LibeditFrame::m_textSize = DEFAULT_SIZE_TEXT; int WinEDA_LibeditFrame:: m_textSize = DEFAULT_SIZE_TEXT;
int WinEDA_LibeditFrame::m_textOrientation = TEXT_ORIENT_HORIZ; int WinEDA_LibeditFrame:: m_textOrientation = TEXT_ORIENT_HORIZ;
int WinEDA_LibeditFrame::m_drawLineWidth = 0; int WinEDA_LibeditFrame:: m_drawLineWidth = 0;
FILL_T WinEDA_LibeditFrame::m_drawFillStyle = NO_FILL; FILL_T WinEDA_LibeditFrame:: m_drawFillStyle = NO_FILL;
/*****************************/ /*****************************/
/* class WinEDA_LibeditFrame */ /* class WinEDA_LibeditFrame */
/*****************************/ /*****************************/
BEGIN_EVENT_TABLE( WinEDA_LibeditFrame, WinEDA_DrawFrame ) BEGIN_EVENT_TABLE( WinEDA_LibeditFrame, WinEDA_DrawFrame )
EVT_CLOSE( WinEDA_LibeditFrame::OnCloseWindow ) EVT_CLOSE( WinEDA_LibeditFrame::OnCloseWindow )
EVT_SIZE( WinEDA_LibeditFrame::OnSize ) EVT_SIZE( WinEDA_LibeditFrame::OnSize )
EVT_ACTIVATE( WinEDA_LibeditFrame::OnActivate ) EVT_ACTIVATE( WinEDA_LibeditFrame::OnActivate )
/* Main horizontal toolbar. */ /* Main horizontal toolbar. */
EVT_TOOL_RANGE( ID_ZOOM_IN, ID_ZOOM_PAGE, WinEDA_LibeditFrame::OnZoom ) EVT_TOOL_RANGE( ID_ZOOM_IN, ID_ZOOM_PAGE, WinEDA_LibeditFrame::OnZoom )
EVT_TOOL( ID_LIBEDIT_SAVE_CURRENT_LIB, EVT_TOOL( ID_LIBEDIT_SAVE_CURRENT_LIB,
WinEDA_LibeditFrame::SaveActiveLibrary ) WinEDA_LibeditFrame::SaveActiveLibrary )
EVT_TOOL( ID_LIBEDIT_SELECT_CURRENT_LIB, EVT_TOOL( ID_LIBEDIT_SELECT_CURRENT_LIB,
WinEDA_LibeditFrame::Process_Special_Functions ) WinEDA_LibeditFrame::Process_Special_Functions )
EVT_TOOL( ID_LIBEDIT_DELETE_PART, EVT_TOOL( ID_LIBEDIT_DELETE_PART,
WinEDA_LibeditFrame::DeleteOnePart ) WinEDA_LibeditFrame::DeleteOnePart )
EVT_TOOL( ID_LIBEDIT_NEW_PART, EVT_TOOL( ID_LIBEDIT_NEW_PART,
WinEDA_LibeditFrame::CreateNewLibraryPart ) WinEDA_LibeditFrame::CreateNewLibraryPart )
EVT_TOOL( ID_LIBEDIT_SELECT_PART, EVT_TOOL( ID_LIBEDIT_SELECT_PART,
WinEDA_LibeditFrame::LoadOneLibraryPart ) WinEDA_LibeditFrame::LoadOneLibraryPart )
EVT_TOOL( ID_LIBEDIT_SAVE_CURRENT_PART, EVT_TOOL( ID_LIBEDIT_SAVE_CURRENT_PART,
WinEDA_LibeditFrame::Process_Special_Functions ) WinEDA_LibeditFrame::Process_Special_Functions )
EVT_TOOL( wxID_UNDO, EVT_TOOL( wxID_UNDO,
WinEDA_LibeditFrame::GetComponentFromUndoList ) WinEDA_LibeditFrame::GetComponentFromUndoList )
EVT_TOOL( wxID_REDO, EVT_TOOL( wxID_REDO,
WinEDA_LibeditFrame::GetComponentFromRedoList ) WinEDA_LibeditFrame::GetComponentFromRedoList )
EVT_TOOL( ID_LIBEDIT_GET_FRAME_EDIT_PART, EVT_TOOL( ID_LIBEDIT_GET_FRAME_EDIT_PART,
WinEDA_LibeditFrame::OnEditComponentProperties ) WinEDA_LibeditFrame::OnEditComponentProperties )
EVT_TOOL( ID_LIBEDIT_GET_FRAME_EDIT_FIELDS, EVT_TOOL( ID_LIBEDIT_GET_FRAME_EDIT_FIELDS,
WinEDA_LibeditFrame::InstallFieldsEditorDialog ) WinEDA_LibeditFrame::InstallFieldsEditorDialog )
EVT_TOOL( ID_LIBEDIT_CHECK_PART, EVT_TOOL( ID_LIBEDIT_CHECK_PART,
WinEDA_LibeditFrame::OnCheckComponent ) WinEDA_LibeditFrame::OnCheckComponent )
EVT_TOOL( ID_DE_MORGAN_NORMAL_BUTT, EVT_TOOL( ID_DE_MORGAN_NORMAL_BUTT,
WinEDA_LibeditFrame::OnSelectBodyStyle ) WinEDA_LibeditFrame::OnSelectBodyStyle )
EVT_TOOL( ID_DE_MORGAN_CONVERT_BUTT, EVT_TOOL( ID_DE_MORGAN_CONVERT_BUTT,
WinEDA_LibeditFrame::OnSelectBodyStyle ) WinEDA_LibeditFrame::OnSelectBodyStyle )
EVT_TOOL( ID_LIBEDIT_VIEW_DOC, EVT_TOOL( ID_LIBEDIT_VIEW_DOC,
WinEDA_LibeditFrame::OnViewEntryDoc ) WinEDA_LibeditFrame::OnViewEntryDoc )
EVT_TOOL( ID_LIBEDIT_EDIT_PIN_BY_PIN, EVT_TOOL( ID_LIBEDIT_EDIT_PIN_BY_PIN,
WinEDA_LibeditFrame::Process_Special_Functions ) WinEDA_LibeditFrame::Process_Special_Functions )
EVT_TOOL( ExportPartId, WinEDA_LibeditFrame::OnExportPart ) EVT_TOOL( ExportPartId, WinEDA_LibeditFrame::OnExportPart )
EVT_TOOL( CreateNewLibAndSavePartId, WinEDA_LibeditFrame::OnExportPart ) EVT_TOOL( CreateNewLibAndSavePartId, WinEDA_LibeditFrame::OnExportPart )
EVT_TOOL( ImportPartId, WinEDA_LibeditFrame::OnImportPart ) EVT_TOOL( ImportPartId, WinEDA_LibeditFrame::OnImportPart )
EVT_KICAD_CHOICEBOX( ID_LIBEDIT_SELECT_PART_NUMBER, EVT_KICAD_CHOICEBOX( ID_LIBEDIT_SELECT_PART_NUMBER,
WinEDA_LibeditFrame::OnSelectPart ) WinEDA_LibeditFrame::OnSelectPart )
EVT_KICAD_CHOICEBOX( ID_LIBEDIT_SELECT_ALIAS, EVT_KICAD_CHOICEBOX( ID_LIBEDIT_SELECT_ALIAS,
WinEDA_LibeditFrame::OnSelectAlias ) WinEDA_LibeditFrame::OnSelectAlias )
/* Right vertical toolbar. */ /* Right vertical toolbar. */
EVT_TOOL( ID_NO_SELECT_BUTT, WinEDA_LibeditFrame::Process_Special_Functions ) EVT_TOOL( ID_NO_SELECT_BUTT, WinEDA_LibeditFrame::Process_Special_Functions )
EVT_TOOL_RANGE( ID_LIBEDIT_PIN_BUTT, ID_LIBEDIT_EXPORT_BODY_BUTT, EVT_TOOL_RANGE( ID_LIBEDIT_PIN_BUTT, ID_LIBEDIT_EXPORT_BODY_BUTT,
WinEDA_LibeditFrame::Process_Special_Functions ) WinEDA_LibeditFrame::Process_Special_Functions )
/* Context menu events and commands. */ /* Context menu events and commands. */
EVT_MENU( ID_LIBEDIT_EDIT_PIN, WinEDA_LibeditFrame::OnEditPin ) EVT_MENU( ID_LIBEDIT_EDIT_PIN, WinEDA_LibeditFrame::OnEditPin )
EVT_MENU( ID_LIBEDIT_ROTATE_PIN, WinEDA_LibeditFrame::OnRotatePin ) EVT_MENU( ID_LIBEDIT_ROTATE_PIN, WinEDA_LibeditFrame::OnRotatePin )
EVT_MENU_RANGE( ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_ITEM, EVT_MENU_RANGE( ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_ITEM,
ID_POPUP_LIBEDIT_ROTATE_GRAPHIC_TEXT, ID_POPUP_LIBEDIT_ROTATE_GRAPHIC_TEXT,
WinEDA_LibeditFrame::Process_Special_Functions ) WinEDA_LibeditFrame::Process_Special_Functions )
EVT_MENU_RANGE( ID_POPUP_GENERAL_START_RANGE, ID_POPUP_GENERAL_END_RANGE, EVT_MENU_RANGE( ID_POPUP_GENERAL_START_RANGE, ID_POPUP_GENERAL_END_RANGE,
WinEDA_LibeditFrame::Process_Special_Functions ) WinEDA_LibeditFrame::Process_Special_Functions )
/* Update user interface elements. */ /* Update user interface elements. */
EVT_UPDATE_UI( ExportPartId, WinEDA_LibeditFrame::OnUpdateEditingPart ) EVT_UPDATE_UI( ExportPartId, WinEDA_LibeditFrame::OnUpdateEditingPart )
EVT_UPDATE_UI( CreateNewLibAndSavePartId, EVT_UPDATE_UI( CreateNewLibAndSavePartId,
WinEDA_LibeditFrame::OnUpdateEditingPart ) WinEDA_LibeditFrame::OnUpdateEditingPart )
EVT_UPDATE_UI( ID_LIBEDIT_SAVE_CURRENT_PART, EVT_UPDATE_UI( ID_LIBEDIT_SAVE_CURRENT_PART,
WinEDA_LibeditFrame::OnUpdateEditingPart ) WinEDA_LibeditFrame::OnUpdateEditingPart )
EVT_UPDATE_UI( ID_LIBEDIT_GET_FRAME_EDIT_FIELDS, EVT_UPDATE_UI( ID_LIBEDIT_GET_FRAME_EDIT_FIELDS,
WinEDA_LibeditFrame::OnUpdateEditingPart ) WinEDA_LibeditFrame::OnUpdateEditingPart )
EVT_UPDATE_UI( ID_LIBEDIT_CHECK_PART, EVT_UPDATE_UI( ID_LIBEDIT_CHECK_PART,
WinEDA_LibeditFrame::OnUpdateEditingPart ) WinEDA_LibeditFrame::OnUpdateEditingPart )
EVT_UPDATE_UI( wxID_UNDO, WinEDA_LibeditFrame::OnUpdateUndo ) EVT_UPDATE_UI( wxID_UNDO, WinEDA_LibeditFrame::OnUpdateUndo )
EVT_UPDATE_UI( wxID_REDO, WinEDA_LibeditFrame::OnUpdateRedo ) EVT_UPDATE_UI( wxID_REDO, WinEDA_LibeditFrame::OnUpdateRedo )
EVT_UPDATE_UI( ID_LIBEDIT_SAVE_CURRENT_LIB, EVT_UPDATE_UI( ID_LIBEDIT_SAVE_CURRENT_LIB,
WinEDA_LibeditFrame::OnUpdateSaveCurrentLib ) WinEDA_LibeditFrame::OnUpdateSaveCurrentLib )
EVT_UPDATE_UI( ID_LIBEDIT_VIEW_DOC, WinEDA_LibeditFrame::OnUpdateViewDoc ) EVT_UPDATE_UI( ID_LIBEDIT_VIEW_DOC, WinEDA_LibeditFrame::OnUpdateViewDoc )
EVT_UPDATE_UI( ID_LIBEDIT_EDIT_PIN_BY_PIN, EVT_UPDATE_UI( ID_LIBEDIT_EDIT_PIN_BY_PIN,
WinEDA_LibeditFrame::OnUpdatePinByPin ) WinEDA_LibeditFrame::OnUpdatePinByPin )
EVT_UPDATE_UI( ID_LIBEDIT_SELECT_PART_NUMBER, EVT_UPDATE_UI( ID_LIBEDIT_SELECT_PART_NUMBER,
WinEDA_LibeditFrame::OnUpdatePartNumber ) WinEDA_LibeditFrame::OnUpdatePartNumber )
EVT_UPDATE_UI( ID_LIBEDIT_SELECT_ALIAS, EVT_UPDATE_UI( ID_LIBEDIT_SELECT_ALIAS,
WinEDA_LibeditFrame::OnUpdateSelectAlias ) WinEDA_LibeditFrame::OnUpdateSelectAlias )
EVT_UPDATE_UI( ID_DE_MORGAN_NORMAL_BUTT, EVT_UPDATE_UI( ID_DE_MORGAN_NORMAL_BUTT,
WinEDA_LibeditFrame::OnUpdateDeMorganNormal ) WinEDA_LibeditFrame::OnUpdateDeMorganNormal )
EVT_UPDATE_UI( ID_DE_MORGAN_CONVERT_BUTT, EVT_UPDATE_UI( ID_DE_MORGAN_CONVERT_BUTT,
WinEDA_LibeditFrame::OnUpdateDeMorganConvert ) WinEDA_LibeditFrame::OnUpdateDeMorganConvert )
EVT_UPDATE_UI_RANGE( ID_LIBEDIT_PIN_BUTT, ID_LIBEDIT_EXPORT_BODY_BUTT, EVT_UPDATE_UI_RANGE( ID_LIBEDIT_PIN_BUTT, ID_LIBEDIT_EXPORT_BODY_BUTT,
WinEDA_LibeditFrame::OnUpdateEditingPart ) WinEDA_LibeditFrame::OnUpdateEditingPart )
END_EVENT_TABLE() END_EVENT_TABLE()
...@@ -638,13 +638,13 @@ void WinEDA_LibeditFrame::Process_Special_Functions( wxCommandEvent& event ) ...@@ -638,13 +638,13 @@ void WinEDA_LibeditFrame::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_LIBEDIT_CANCEL_EDITING: case ID_POPUP_LIBEDIT_CANCEL_EDITING:
if( DrawPanel->ManageCurseur && DrawPanel->ForceCloseManageCurseur ) if( DrawPanel->ManageCurseur && DrawPanel->ForceCloseManageCurseur )
DrawPanel->UnManageCursor( ); DrawPanel->UnManageCursor();
else else
DrawPanel->UnManageCursor( 0, wxCURSOR_ARROW ); DrawPanel->UnManageCursor( 0, wxCURSOR_ARROW );
break; break;
case ID_POPUP_LIBEDIT_DELETE_ITEM: case ID_POPUP_LIBEDIT_DELETE_ITEM:
DrawPanel->UnManageCursor( ); DrawPanel->UnManageCursor();
break; break;
default: default:
...@@ -653,6 +653,7 @@ void WinEDA_LibeditFrame::Process_Special_Functions( wxCommandEvent& event ) ...@@ -653,6 +653,7 @@ void WinEDA_LibeditFrame::Process_Special_Functions( wxCommandEvent& event )
} }
INSTALL_DC( dc, DrawPanel ); INSTALL_DC( dc, DrawPanel );
switch( id ) switch( id )
{ {
case ID_POPUP_LIBEDIT_CANCEL_EDITING: case ID_POPUP_LIBEDIT_CANCEL_EDITING:
...@@ -815,6 +816,24 @@ void WinEDA_LibeditFrame::Process_Special_Functions( wxCommandEvent& event ) ...@@ -815,6 +816,24 @@ void WinEDA_LibeditFrame::Process_Special_Functions( wxCommandEvent& event )
StartMoveDrawSymbol( &dc ); StartMoveDrawSymbol( &dc );
break; break;
case ID_POPUP_LIBEDIT_MODIFY_ITEM:
if( m_drawItem == NULL )
break;
DrawPanel->MouseToCursorSchema();
if( m_drawItem->Type() == COMPONENT_RECT_DRAW_TYPE
|| m_drawItem->Type() == COMPONENT_CIRCLE_DRAW_TYPE
|| m_drawItem->Type() == COMPONENT_POLYLINE_DRAW_TYPE
|| m_drawItem->Type() == COMPONENT_ARC_DRAW_TYPE
)
{
SaveCopyInUndoList( m_component );
StartModifyDrawSymbol( &dc );
}
break;
case ID_POPUP_LIBEDIT_ROTATE_GRAPHIC_TEXT: case ID_POPUP_LIBEDIT_ROTATE_GRAPHIC_TEXT:
if( m_drawItem == NULL ) if( m_drawItem == NULL )
break; break;
...@@ -914,6 +933,7 @@ void WinEDA_LibeditFrame::Process_Special_Functions( wxCommandEvent& event ) ...@@ -914,6 +933,7 @@ void WinEDA_LibeditFrame::Process_Special_Functions( wxCommandEvent& event )
m_lastDrawItem = NULL; m_lastDrawItem = NULL;
} }
/** Called on activate the frame. /** Called on activate the frame.
* Test if the current library exists * Test if the current library exists
* the library list can be changed by the schematic editor after reloading a new schematic * the library list can be changed by the schematic editor after reloading a new schematic
...@@ -928,13 +948,14 @@ void WinEDA_LibeditFrame::OnActivate( wxActivateEvent& event ) ...@@ -928,13 +948,14 @@ void WinEDA_LibeditFrame::OnActivate( wxActivateEvent& event )
EnsureActiveLibExists(); EnsureActiveLibExists();
} }
void WinEDA_LibeditFrame::EnsureActiveLibExists() void WinEDA_LibeditFrame::EnsureActiveLibExists()
{ {
if( m_library == NULL ) if( m_library == NULL )
return; return;
bool exists = CMP_LIBRARY::LibraryExists( m_library ); bool exists = CMP_LIBRARY::LibraryExists( m_library );
if ( exists ) if( exists )
return; return;
else else
m_library = NULL; m_library = NULL;
......
...@@ -247,7 +247,7 @@ void AddMenusForComponentField( wxMenu* PopMenu, SCH_FIELD* Field ) ...@@ -247,7 +247,7 @@ void AddMenusForComponentField( wxMenu* PopMenu, SCH_FIELD* Field )
} }
msg = AddHotkeyName( _( "Rotate Field" ), msg = AddHotkeyName( _( "Rotate Field" ),
s_Schematic_Hokeys_Descr, HK_ROTATE_COMPONENT_OR_ITEM ); s_Schematic_Hokeys_Descr, HK_ROTATE );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_ROTATE_FIELD, ADD_MENUITEM( PopMenu, ID_POPUP_SCH_ROTATE_FIELD,
msg, rotate_field_xpm ); msg, rotate_field_xpm );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_EDIT_FIELD, ADD_MENUITEM( PopMenu, ID_POPUP_SCH_EDIT_FIELD,
...@@ -285,14 +285,14 @@ void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component ) ...@@ -285,14 +285,14 @@ void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component )
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_MOVE_CMP_REQUEST, ADD_MENUITEM( PopMenu, ID_POPUP_SCH_MOVE_CMP_REQUEST,
msg, move_xpm ); msg, move_xpm );
msg = AddHotkeyName( _( "Drag Component" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Drag Component" ), s_Schematic_Hokeys_Descr,
HK_DRAG_COMPONENT ); HK_DRAG );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_DRAG_CMP_REQUEST, ADD_MENUITEM( PopMenu, ID_POPUP_SCH_DRAG_CMP_REQUEST,
msg, move_xpm ); msg, move_xpm );
} }
wxMenu* orientmenu = new wxMenu; wxMenu* orientmenu = new wxMenu;
msg = AddHotkeyName( _( "Rotate +" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Rotate +" ), s_Schematic_Hokeys_Descr,
HK_ROTATE_COMPONENT_OR_ITEM ); HK_ROTATE );
ADD_MENUITEM( orientmenu, ID_POPUP_SCH_ROTATE_CMP_COUNTERCLOCKWISE, ADD_MENUITEM( orientmenu, ID_POPUP_SCH_ROTATE_CMP_COUNTERCLOCKWISE,
msg, rotate_pos_xpm ); msg, rotate_pos_xpm );
ADD_MENUITEM( orientmenu, ID_POPUP_SCH_ROTATE_CMP_CLOCKWISE, ADD_MENUITEM( orientmenu, ID_POPUP_SCH_ROTATE_CMP_CLOCKWISE,
...@@ -312,7 +312,7 @@ void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component ) ...@@ -312,7 +312,7 @@ void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component )
wxMenu* editmenu = new wxMenu; wxMenu* editmenu = new wxMenu;
msg = AddHotkeyName( _( "Edit" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Edit" ), s_Schematic_Hokeys_Descr,
HK_EDIT_COMPONENT_OR_LABEL ); HK_EDIT );
ADD_MENUITEM( editmenu, ID_POPUP_SCH_EDIT_CMP, msg, ADD_MENUITEM( editmenu, ID_POPUP_SCH_EDIT_CMP, msg,
edit_component_xpm ); edit_component_xpm );
...@@ -393,11 +393,11 @@ void AddMenusForGLabel( wxMenu* PopMenu, SCH_GLOBALLABEL* GLabel ) ...@@ -393,11 +393,11 @@ void AddMenusForGLabel( wxMenu* PopMenu, SCH_GLOBALLABEL* GLabel )
msg, copy_button ); msg, copy_button );
} }
msg = AddHotkeyName( _( "Rotate Global Label" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Rotate Global Label" ), s_Schematic_Hokeys_Descr,
HK_ROTATE_COMPONENT_OR_ITEM ); HK_ROTATE );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_ROTATE_TEXT, ADD_MENUITEM( PopMenu, ID_POPUP_SCH_ROTATE_TEXT,
msg, rotate_glabel_xpm ); msg, rotate_glabel_xpm );
msg = AddHotkeyName( _( "Edit Global Label" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Edit Global Label" ), s_Schematic_Hokeys_Descr,
HK_EDIT_COMPONENT_OR_LABEL ); HK_EDIT );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_EDIT_TEXT, ADD_MENUITEM( PopMenu, ID_POPUP_SCH_EDIT_TEXT,
msg, edit_text_xpm ); msg, edit_text_xpm );
msg = AddHotkeyName( _( "Delete Global Label" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Delete Global Label" ), s_Schematic_Hokeys_Descr,
...@@ -437,11 +437,11 @@ void AddMenusForHLabel( wxMenu* PopMenu, SCH_HIERLABEL* HLabel ) ...@@ -437,11 +437,11 @@ void AddMenusForHLabel( wxMenu* PopMenu, SCH_HIERLABEL* HLabel )
msg, copy_button ); msg, copy_button );
} }
msg = AddHotkeyName( _( "Rotate Hierarchical Label" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Rotate Hierarchical Label" ), s_Schematic_Hokeys_Descr,
HK_ROTATE_COMPONENT_OR_ITEM ); HK_ROTATE );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_ROTATE_TEXT, ADD_MENUITEM( PopMenu, ID_POPUP_SCH_ROTATE_TEXT,
_( "Rotate Hierarchical Label" ), rotate_glabel_xpm ); _( "Rotate Hierarchical Label" ), rotate_glabel_xpm );
msg = AddHotkeyName( _( "Edit Hierarchical Label" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Edit Hierarchical Label" ), s_Schematic_Hokeys_Descr,
HK_EDIT_COMPONENT_OR_LABEL ); HK_EDIT );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_EDIT_TEXT, ADD_MENUITEM( PopMenu, ID_POPUP_SCH_EDIT_TEXT,
_( "Edit Hierarchical Label" ), edit_text_xpm ); _( "Edit Hierarchical Label" ), edit_text_xpm );
msg = AddHotkeyName( _( "Delete Hierarchical Label" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Delete Hierarchical Label" ), s_Schematic_Hokeys_Descr,
...@@ -480,11 +480,11 @@ void AddMenusForLabel( wxMenu* PopMenu, SCH_LABEL* Label ) ...@@ -480,11 +480,11 @@ void AddMenusForLabel( wxMenu* PopMenu, SCH_LABEL* Label )
msg, copy_button ); msg, copy_button );
} }
msg = AddHotkeyName( _( "Rotate Label" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Rotate Label" ), s_Schematic_Hokeys_Descr,
HK_ROTATE_COMPONENT_OR_ITEM ); HK_ROTATE );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_ROTATE_TEXT, ADD_MENUITEM( PopMenu, ID_POPUP_SCH_ROTATE_TEXT,
msg, rotate_pos_xpm ); msg, rotate_pos_xpm );
msg = AddHotkeyName( _( "Edit Label" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Edit Label" ), s_Schematic_Hokeys_Descr,
HK_EDIT_COMPONENT_OR_LABEL ); HK_EDIT );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_EDIT_TEXT, ADD_MENUITEM( PopMenu, ID_POPUP_SCH_EDIT_TEXT,
msg, edit_text_xpm ); msg, edit_text_xpm );
msg = AddHotkeyName( _( "Delete Label" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Delete Label" ), s_Schematic_Hokeys_Descr,
...@@ -524,11 +524,11 @@ void AddMenusForText( wxMenu* PopMenu, SCH_TEXT* Text ) ...@@ -524,11 +524,11 @@ void AddMenusForText( wxMenu* PopMenu, SCH_TEXT* Text )
msg, copy_button ); msg, copy_button );
} }
msg = AddHotkeyName( _( "Rotate Text" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Rotate Text" ), s_Schematic_Hokeys_Descr,
HK_ROTATE_COMPONENT_OR_ITEM ); HK_ROTATE );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_ROTATE_TEXT, msg, ADD_MENUITEM( PopMenu, ID_POPUP_SCH_ROTATE_TEXT, msg,
rotate_pos_xpm ); rotate_pos_xpm );
msg = AddHotkeyName( _( "Edit Text" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Edit Text" ), s_Schematic_Hokeys_Descr,
HK_EDIT_COMPONENT_OR_LABEL ); HK_EDIT );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_EDIT_TEXT, msg, ADD_MENUITEM( PopMenu, ID_POPUP_SCH_EDIT_TEXT, msg,
edit_text_xpm ); edit_text_xpm );
msg = AddHotkeyName( _( "Delete Text" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Delete Text" ), s_Schematic_Hokeys_Descr,
...@@ -601,7 +601,7 @@ void AddMenusForWire( wxMenu* PopMenu, SCH_LINE* Wire, ...@@ -601,7 +601,7 @@ void AddMenusForWire( wxMenu* PopMenu, SCH_LINE* Wire,
} }
msg = AddHotkeyName( _( "Drag Wire" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Drag Wire" ), s_Schematic_Hokeys_Descr,
HK_DRAG_COMPONENT ); HK_DRAG );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_DRAG_WIRE_REQUEST, msg, ADD_MENUITEM( PopMenu, ID_POPUP_SCH_DRAG_WIRE_REQUEST, msg,
move_track_xpm ); move_track_xpm );
PopMenu->AppendSeparator(); PopMenu->AppendSeparator();
...@@ -688,7 +688,7 @@ void AddMenusForHierchicalSheet( wxMenu* PopMenu, SCH_SHEET* Sheet ) ...@@ -688,7 +688,7 @@ void AddMenusForHierchicalSheet( wxMenu* PopMenu, SCH_SHEET* Sheet )
else else
{ {
msg = AddHotkeyName( _( "Edit Sheet" ), msg = AddHotkeyName( _( "Edit Sheet" ),
s_Schematic_Hokeys_Descr, HK_EDIT_COMPONENT_OR_LABEL ); s_Schematic_Hokeys_Descr, HK_EDIT );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_EDIT_SHEET, msg, ADD_MENUITEM( PopMenu, ID_POPUP_SCH_EDIT_SHEET, msg,
edit_sheet_xpm ); edit_sheet_xpm );
......
...@@ -20,17 +20,44 @@ ...@@ -20,17 +20,44 @@
#include "class_libentry.h" #include "class_libentry.h"
#include "dialog_lib_edit_draw_item.h" #include "dialog_lib_edit_draw_item.h"
#include <boost/foreach.hpp>
#define EraseItem( item ) item->Draw( Panel, DC, wxPoint( 0,\
0 ), -1, g_XorMode, NULL,\
DefaultTransformMatrix )
static void SymbolDisplayDraw( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ); static void SymbolDisplayDraw( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
static void ComputeArc( LIB_ARC* DrawItem, wxPoint ArcCentre ); 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, static void RedrawWhileMovingCursor( WinEDA_DrawPanel* panel,
wxDC* DC, wxDC* DC,
bool erase ); bool erase );
static int StateDrawArc, ArcStartX, ArcStartY, ArcEndX, ArcEndY;
static wxPoint InitPosition, StartCursor, ItemPreviousPos; static wxPoint InitPosition, StartCursor, ItemPreviousPos;
typedef enum {
START_POINT, END_POINT, OUTLINE
} 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
...@@ -42,31 +69,31 @@ void WinEDA_LibeditFrame::EditGraphicSymbol( wxDC* DC, LIB_DRAW_ITEM* DrawItem ) ...@@ -42,31 +69,31 @@ void WinEDA_LibeditFrame::EditGraphicSymbol( wxDC* DC, LIB_DRAW_ITEM* DrawItem )
LIB_COMPONENT* component = DrawItem->GetParent(); LIB_COMPONENT* component = DrawItem->GetParent();
DIALOG_LIB_EDIT_DRAW_ITEM dlg( this, DrawItem->m_typeName ); DIALOG_LIB_EDIT_DRAW_ITEM dialog( this, DrawItem->m_typeName );
dlg.SetWidthUnits( ReturnUnitSymbol( g_UnitMetric ) ); dialog.SetWidthUnits( ReturnUnitSymbol( g_UnitMetric ) );
wxString val = ReturnStringFromValue( g_UnitMetric, m_drawLineWidth, wxString val = ReturnStringFromValue( g_UnitMetric, m_drawLineWidth,
m_InternalUnits ); m_InternalUnits );
dlg.SetWidth( val ); dialog.SetWidth( val );
dlg.SetApplyToAllUnits( !m_drawSpecificUnit ); dialog.SetApplyToAllUnits( !m_drawSpecificUnit );
dlg.EnableApplyToAllUnits( component && component->GetPartCount() > 1 ); dialog.EnableApplyToAllUnits( component && component->GetPartCount() > 1 );
dlg.SetApplyToAllConversions( !m_drawSpecificConvert ); dialog.SetApplyToAllConversions( !m_drawSpecificConvert );
dlg.EnableApplyToAllConversions( component && component->HasConversion() ); dialog.EnableApplyToAllConversions( component && component->HasConversion() );
dlg.SetFillStyle( m_drawFillStyle ); dialog.SetFillStyle( m_drawFillStyle );
dlg.EnableFillStyle( DrawItem->IsFillable() ); dialog.EnableFillStyle( DrawItem->IsFillable() );
if( dlg.ShowModal() == wxID_CANCEL ) if( dialog.ShowModal() == wxID_CANCEL )
return; return;
val = dlg.GetWidth(); val = dialog.GetWidth();
m_drawLineWidth = ReturnValueFromString( g_UnitMetric, val, m_drawLineWidth = ReturnValueFromString( g_UnitMetric, val,
m_InternalUnits ); m_InternalUnits );
m_drawSpecificConvert = !dlg.GetApplyToAllConversions(); m_drawSpecificConvert = !dialog.GetApplyToAllConversions();
m_drawSpecificUnit = !dlg.GetApplyToAllUnits(); m_drawSpecificUnit = !dialog.GetApplyToAllUnits();
if( DrawItem->IsFillable() ) if( DrawItem->IsFillable() )
m_drawFillStyle = (FILL_T) dlg.GetFillStyle(); m_drawFillStyle = (FILL_T) dialog.GetFillStyle();
// Save copy for undo is done before place. // Save copy for undo is done before place.
if( !( DrawItem->m_Flags & IS_NEW ) ) if( !( DrawItem->m_Flags & IS_NEW ) )
...@@ -99,14 +126,14 @@ void WinEDA_LibeditFrame::EditGraphicSymbol( wxDC* DC, LIB_DRAW_ITEM* DrawItem ) ...@@ -99,14 +126,14 @@ 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; LIB_DRAW_ITEM* item;
WinEDA_LibeditFrame* parent = ( WinEDA_LibeditFrame* ) Panel->GetParent(); WinEDA_LibeditFrame* parent = (WinEDA_LibeditFrame*) Panel->GetParent();
item = parent->GetDrawItem(); item = parent->GetDrawItem();
if( item == NULL ) if( item == NULL )
return; return;
StateDrawArc = 0; arcState.stateDrawArc = 0;
Panel->ManageCurseur = NULL; Panel->ManageCurseur = NULL;
Panel->ForceCloseManageCurseur = NULL; Panel->ForceCloseManageCurseur = NULL;
...@@ -115,7 +142,7 @@ static void AbortSymbolTraceOn( WinEDA_DrawPanel* Panel, wxDC* DC ) ...@@ -115,7 +142,7 @@ static void AbortSymbolTraceOn( WinEDA_DrawPanel* Panel, wxDC* DC )
if( DC ) if( DC )
{ {
if( item->Type() == COMPONENT_ARC_DRAW_TYPE ) if( item->Type() == COMPONENT_ARC_DRAW_TYPE )
Panel->GetParent()->DrawPanel->Refresh( ); Panel->GetParent()->DrawPanel->Refresh();
else else
item->Draw( Panel, DC, wxPoint( 0, 0 ), -1, g_XorMode, NULL, item->Draw( Panel, DC, wxPoint( 0, 0 ), -1, g_XorMode, NULL,
DefaultTransformMatrix ); DefaultTransformMatrix );
...@@ -125,11 +152,54 @@ static void AbortSymbolTraceOn( WinEDA_DrawPanel* Panel, wxDC* DC ) ...@@ -125,11 +152,54 @@ static void AbortSymbolTraceOn( WinEDA_DrawPanel* Panel, wxDC* DC )
parent->SetDrawItem( NULL ); parent->SetDrawItem( NULL );
} }
else else
{
// Restore old attributes, when the item was modified
if( item->m_Flags == IS_RESIZED )
{
EraseItem( item );
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; wxPoint curpos = Panel->GetScreen()->m_Curseur;
Panel->GetScreen()->m_Curseur = StartCursor; Panel->GetScreen()->m_Curseur = StartCursor;
RedrawWhileMovingCursor( Panel, DC, TRUE ); RedrawWhileMovingCursor( Panel, DC, TRUE );
Panel->GetScreen()->m_Curseur = curpos; Panel->GetScreen()->m_Curseur = curpos;
}
item->Draw( Panel, DC, wxPoint( 0, 0 ), -1, GR_DEFAULT_DRAWMODE, NULL, item->Draw( Panel, DC, wxPoint( 0, 0 ), -1, GR_DEFAULT_DRAWMODE, NULL,
DefaultTransformMatrix ); DefaultTransformMatrix );
item->m_Flags = 0; item->m_Flags = 0;
...@@ -150,9 +220,9 @@ LIB_DRAW_ITEM* WinEDA_LibeditFrame::CreateGraphicItem( LIB_COMPONENT* LibEntry, ...@@ -150,9 +220,9 @@ LIB_DRAW_ITEM* WinEDA_LibeditFrame::CreateGraphicItem( LIB_COMPONENT* LibEntry,
LIB_ARC* Arc = new LIB_ARC( LibEntry ); LIB_ARC* Arc = new LIB_ARC( LibEntry );
m_drawItem = Arc; m_drawItem = Arc;
ArcStartX = ArcEndX = GetScreen()->m_Curseur.x; arcState.startPoint.x = arcState.endPoint.x = GetScreen()->m_Curseur.x;
ArcStartY = ArcEndY = -( GetScreen()->m_Curseur.y ); arcState.startPoint.y = arcState.endPoint.y = -( GetScreen()->m_Curseur.y );
StateDrawArc = 1; arcState.stateDrawArc = 1;
Arc->m_Fill = m_drawFillStyle; Arc->m_Fill = m_drawFillStyle;
Arc->m_Width = m_drawLineWidth; Arc->m_Width = m_drawLineWidth;
} }
...@@ -272,14 +342,14 @@ void WinEDA_LibeditFrame::GraphicItemBeginDraw( wxDC* DC ) ...@@ -272,14 +342,14 @@ void WinEDA_LibeditFrame::GraphicItemBeginDraw( wxDC* DC )
switch( m_drawItem->Type() ) switch( m_drawItem->Type() )
{ {
case COMPONENT_ARC_DRAW_TYPE: case COMPONENT_ARC_DRAW_TYPE:
if( StateDrawArc == 1 ) if( arcState.stateDrawArc == 1 )
{ {
SymbolDisplayDraw( DrawPanel, DC, FALSE ); SymbolDisplayDraw( DrawPanel, DC, FALSE );
StateDrawArc = 2; arcState.stateDrawArc = 2;
SymbolDisplayDraw( DrawPanel, DC, FALSE ); SymbolDisplayDraw( DrawPanel, DC, FALSE );
break; break;
} }
if( StateDrawArc > 1 ) if( arcState.stateDrawArc > 1 )
{ {
EndDrawGraphicItem( DC ); EndDrawGraphicItem( DC );
return; return;
...@@ -318,7 +388,7 @@ static void RedrawWhileMovingCursor( WinEDA_DrawPanel* panel, ...@@ -318,7 +388,7 @@ static void RedrawWhileMovingCursor( WinEDA_DrawPanel* panel,
{ {
LIB_DRAW_ITEM* item; LIB_DRAW_ITEM* item;
item = ( ( WinEDA_LibeditFrame* ) panel->GetParent() )->GetDrawItem(); item = ( (WinEDA_LibeditFrame*) panel->GetParent() )->GetDrawItem();
if( item == NULL ) if( item == NULL )
return; return;
...@@ -358,47 +428,200 @@ void WinEDA_LibeditFrame::StartMoveDrawSymbol( wxDC* DC ) ...@@ -358,47 +428,200 @@ void WinEDA_LibeditFrame::StartMoveDrawSymbol( wxDC* DC )
} }
/* Manage mouse events when creating new graphic object. */ // @brief Modify a graphic symbol (drag edges etc.)
void WinEDA_LibeditFrame::StartModifyDrawSymbol( wxDC* DC )
{
if( m_drawItem == NULL )
return;
// TODO Check if this is really required
StartCursor = GetScreen()->m_Curseur;
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->ForceCloseManageCurseur = AbortSymbolTraceOn;
DrawPanel->ManageCurseur( DrawPanel, DC, TRUE );
}
//! @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 dx, dy;
int DrawMode = g_XorMode; int DrawMode = g_XorMode;
BASE_SCREEN* Screen = panel->GetScreen(); BASE_SCREEN* Screen = panel->GetScreen();
wxPoint curr_pos = Screen->m_Curseur; wxPoint currentCursorPosition = Screen->m_Curseur;
FILL_T fillStyle = NO_FILL; FILL_T fillStyle = NO_FILL;
LIB_DRAW_ITEM* item; LIB_DRAW_ITEM* item;
item = ( ( WinEDA_LibeditFrame* ) panel->GetParent() )->GetDrawItem(); item = ( (WinEDA_LibeditFrame*) panel->GetParent() )->GetDrawItem();
if( item == NULL ) if( item == NULL )
return; return;
fillStyle = ( ( WinEDA_LibeditFrame* ) panel->GetParent() )->GetFillStyle(); fillStyle = ( (WinEDA_LibeditFrame*) panel->GetParent() )->GetFillStyle();
NEGATE( curr_pos.y ); NEGATE( currentCursorPosition.y );
GRSetDrawMode( DC, DrawMode ); GRSetDrawMode( DC, DrawMode );
if( erase ) if( erase )
{ {
if( StateDrawArc == 1 ) if( arcState.stateDrawArc == 1 )
{ {
int Color = ReturnLayerColor( LAYER_DEVICE ); int Color = ReturnLayerColor( LAYER_DEVICE );
GRLine( &panel->m_ClipBox, DC, ArcStartX, -ArcStartY, GRLine( &panel->m_ClipBox, DC, arcState.startPoint.x, -arcState.startPoint.y,
ArcEndX, -ArcEndY, 0, Color ); arcState.endPoint.x, -arcState.endPoint.y, 0, Color );
} }
else else
{ {
item->Draw( panel, DC, wxPoint( 0, 0 ), -1, DrawMode, NULL, item->Draw( panel, DC, wxPoint( 0, 0 ), -1, DrawMode, NULL,
DefaultTransformMatrix ); DefaultTransformMatrix );
if( item->Type() == COMPONENT_ARC_DRAW_TYPE )
if( item->Type() == COMPONENT_ARC_DRAW_TYPE && item->m_Flags != IS_RESIZED )
{ {
int Color = ReturnLayerColor( LAYER_DEVICE ); int Color = ReturnLayerColor( LAYER_DEVICE );
GRDashedLine( &panel->m_ClipBox, DC, ArcStartX, -ArcStartY, GRDashedLine( &panel->m_ClipBox, DC, arcState.startPoint.x, -arcState.startPoint.y,
( (LIB_ARC*) item )->m_Pos.x, ( (LIB_ARC*) item )->m_Pos.x,
-( (LIB_ARC*) item )->m_Pos.y, -( (LIB_ARC*) item )->m_Pos.y,
0, Color ); 0, Color );
GRDashedLine( &panel->m_ClipBox, DC, ArcEndX, -ArcEndY, GRDashedLine( &panel->m_ClipBox, DC, arcState.endPoint.x, -arcState.endPoint.y,
( (LIB_ARC*) item )->m_Pos.x, ( (LIB_ARC*) item )->m_Pos.x,
-( (LIB_ARC*) item )->m_Pos.y, -( (LIB_ARC*) item )->m_Pos.y,
0, Color ); 0, Color );
...@@ -409,42 +632,168 @@ static void SymbolDisplayDraw( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ) ...@@ -409,42 +632,168 @@ static void SymbolDisplayDraw( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
switch( item->Type() ) switch( item->Type() )
{ {
case COMPONENT_ARC_DRAW_TYPE: case COMPONENT_ARC_DRAW_TYPE:
if( StateDrawArc == 1 ) 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
{ {
ArcEndX = curr_pos.x; newCenterPoint = ( (LIB_ARC*) item )->m_Pos;
ArcEndY = curr_pos.y;
} }
if( StateDrawArc == 2 ) // 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 ); ComputeArc( (LIB_ARC*) item, Screen->m_Curseur );
} }
item ->m_Fill = fillStyle; item->m_Fill = fillStyle;
}
break; break;
case COMPONENT_CIRCLE_DRAW_TYPE: case COMPONENT_CIRCLE_DRAW_TYPE:
dx = ( (LIB_CIRCLE*) item )->m_Pos.x - curr_pos.x; dx = ( (LIB_CIRCLE*) item )->m_Pos.x - currentCursorPosition.x;
dy = ( (LIB_CIRCLE*) item )->m_Pos.y - curr_pos.y; dy = ( (LIB_CIRCLE*) item )->m_Pos.y - currentCursorPosition.y;
( (LIB_CIRCLE*) item )->m_Radius = ( (LIB_CIRCLE*) item )->m_Radius =
(int) sqrt( ( (double) dx * dx ) + ( (double) dy * dy ) ); (int) sqrt( ( (double) dx * dx ) + ( (double) dy * dy ) );
item->m_Fill = fillStyle; item->m_Fill = fillStyle;
break; break;
case COMPONENT_RECT_DRAW_TYPE: case COMPONENT_RECT_DRAW_TYPE:
( (LIB_RECTANGLE*) item )->m_End = curr_pos; 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; item->m_Fill = fillStyle;
break; break;
case COMPONENT_POLYLINE_DRAW_TYPE: case COMPONENT_POLYLINE_DRAW_TYPE:
{ {
unsigned idx = ( (LIB_POLYLINE*) item )->GetCornerCount() - 1; unsigned idx;
( (LIB_POLYLINE*) item )->m_PolyPoints[idx] = curr_pos;
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; item->m_Fill = fillStyle;
} }
break; break;
case COMPONENT_LINE_DRAW_TYPE: case COMPONENT_LINE_DRAW_TYPE:
( (LIB_SEGMENT*) item )->m_End = curr_pos; ( (LIB_SEGMENT*) item )->m_End = currentCursorPosition;
break; break;
case COMPONENT_GRAPHIC_TEXT_DRAW_TYPE: case COMPONENT_GRAPHIC_TEXT_DRAW_TYPE:
...@@ -454,25 +803,31 @@ static void SymbolDisplayDraw( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ) ...@@ -454,25 +803,31 @@ static void SymbolDisplayDraw( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
; ;
} }
if( StateDrawArc == 1 ) if( arcState.stateDrawArc == 1 )
{ {
int Color = ReturnLayerColor( LAYER_DEVICE ); int Color = ReturnLayerColor( LAYER_DEVICE );
GRLine( &panel->m_ClipBox, DC, ArcStartX, -ArcStartY, ArcEndX, GRLine( &panel->m_ClipBox,
-ArcEndY, 0, Color ); DC,
arcState.startPoint.x,
-arcState.startPoint.y,
arcState.endPoint.x,
-arcState.endPoint.y,
0,
Color );
} }
else else
{ {
item->Draw( panel, DC, wxPoint( 0, 0 ), -1, DrawMode, NULL, item->Draw( panel, DC, wxPoint( 0, 0 ), -1, DrawMode, NULL,
DefaultTransformMatrix ); DefaultTransformMatrix );
if( item->Type() == COMPONENT_ARC_DRAW_TYPE ) if( item->Type() == COMPONENT_ARC_DRAW_TYPE && item->m_Flags != IS_RESIZED )
{ {
int Color = ReturnLayerColor( LAYER_DEVICE ); int Color = ReturnLayerColor( LAYER_DEVICE );
GRDashedLine( &panel->m_ClipBox, DC, ArcStartX, -ArcStartY, GRDashedLine( &panel->m_ClipBox, DC, arcState.startPoint.x, -arcState.startPoint.y,
( (LIB_ARC*) item )->m_Pos.x, ( (LIB_ARC*) item )->m_Pos.x,
-( (LIB_ARC*) item )->m_Pos.y, -( (LIB_ARC*) item )->m_Pos.y,
0, Color ); 0, Color );
GRDashedLine( &panel->m_ClipBox, DC, ArcEndX, -ArcEndY, GRDashedLine( &panel->m_ClipBox, DC, arcState.endPoint.x, -arcState.endPoint.y,
( (LIB_ARC*) item )->m_Pos.x, ( (LIB_ARC*) item )->m_Pos.x,
-( (LIB_ARC*) item )->m_Pos.y, -( (LIB_ARC*) item )->m_Pos.y,
0, Color ); 0, Color );
...@@ -491,7 +846,7 @@ void WinEDA_LibeditFrame::EndDrawGraphicItem( wxDC* DC ) ...@@ -491,7 +846,7 @@ void WinEDA_LibeditFrame::EndDrawGraphicItem( wxDC* DC )
if( m_drawItem->Type() == COMPONENT_ARC_DRAW_TYPE ) if( m_drawItem->Type() == COMPONENT_ARC_DRAW_TYPE )
{ {
if( StateDrawArc == 1 ) /* Trace arc under way must be completed. */ if( arcState.stateDrawArc == 1 ) /* Trace arc under way must be completed. */
{ {
DisplayError( this, wxT( "Arc in progress.." ) ); DisplayError( this, wxT( "Arc in progress.." ) );
return; return;
...@@ -503,7 +858,7 @@ void WinEDA_LibeditFrame::EndDrawGraphicItem( wxDC* DC ) ...@@ -503,7 +858,7 @@ void WinEDA_LibeditFrame::EndDrawGraphicItem( wxDC* DC )
} }
} }
StateDrawArc = 0; arcState.stateDrawArc = 0;
if( m_drawItem->m_Flags & IS_NEW ) if( m_drawItem->m_Flags & IS_NEW )
{ {
...@@ -522,6 +877,8 @@ void WinEDA_LibeditFrame::EndDrawGraphicItem( wxDC* DC ) ...@@ -522,6 +877,8 @@ void WinEDA_LibeditFrame::EndDrawGraphicItem( wxDC* DC )
case COMPONENT_RECT_DRAW_TYPE: case COMPONENT_RECT_DRAW_TYPE:
( (LIB_RECTANGLE*) m_drawItem )->m_Fill = m_drawFillStyle; ( (LIB_RECTANGLE*) m_drawItem )->m_Fill = m_drawFillStyle;
( (LIB_RECTANGLE*) m_drawItem )->m_isHeightLocked = false;
( (LIB_RECTANGLE*) m_drawItem )->m_isWidthLocked = false;
break; break;
case COMPONENT_POLYLINE_DRAW_TYPE: case COMPONENT_POLYLINE_DRAW_TYPE:
...@@ -565,10 +922,60 @@ void WinEDA_LibeditFrame::EndDrawGraphicItem( wxDC* DC ) ...@@ -565,10 +922,60 @@ void WinEDA_LibeditFrame::EndDrawGraphicItem( wxDC* DC )
} }
//! @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 = 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. * Routine for adjusting the parameters of the arc currently being drawn.
* Calculates the center, radius, angles for the arc current * Calculates the center, radius, angles for the arc current
* Passes through the points ArcStartX, ArcEndX Y and Y with the nearest center * Passes through the points arcState.startPoint.x, arcState.endPoint.x Y and Y with the nearest center
* of the mouse position. * of the mouse position.
* Note: The center is obviously not on the grid * Note: The center is obviously not on the grid
*/ */
...@@ -583,12 +990,12 @@ static void ComputeArc( LIB_ARC* DrawItem, wxPoint ArcCentre ) ...@@ -583,12 +990,12 @@ static void ComputeArc( LIB_ARC* DrawItem, wxPoint ArcCentre )
cY = -cY; /* Attention to the orientation of the axis Y. */ cY = -cY; /* Attention to the orientation of the axis Y. */
/* Calculating cX and cY for the arc passes through ArcStartX, ArcEndX, /* Calculating cX and cY for the arc passes through arcState.startPoint.x, arcState.endPoint.x,
* X and Y */ * X and Y */
dx = ArcEndX - ArcStartX; dx = arcState.endPoint.x - arcState.startPoint.x;
dy = ArcEndY - ArcStartY; dy = arcState.endPoint.y - arcState.startPoint.y;
cX -= ArcStartX; cX -= arcState.startPoint.x;
cY -= ArcStartY; cY -= arcState.startPoint.y;
angle = (int) ( atan2( (double) dy, (double) dx ) * 1800 / M_PI ); angle = (int) ( atan2( (double) dy, (double) dx ) * 1800 / M_PI );
RotatePoint( &dx, &dy, angle ); /* The segment dx, dy is horizontal RotatePoint( &dx, &dy, angle ); /* The segment dx, dy is horizontal
* -> Length = dx, dy = 0 */ * -> Length = dx, dy = 0 */
...@@ -596,28 +1003,28 @@ static void ComputeArc( LIB_ARC* DrawItem, wxPoint ArcCentre ) ...@@ -596,28 +1003,28 @@ static void ComputeArc( LIB_ARC* DrawItem, wxPoint ArcCentre )
cX = dx / 2; /* cX, cY is on the median segment 0.0 a dx, 0 */ cX = dx / 2; /* cX, cY is on the median segment 0.0 a dx, 0 */
RotatePoint( &cX, &cY, -angle ); RotatePoint( &cX, &cY, -angle );
cX += ArcStartX; cX += arcState.startPoint.x;
cY += ArcStartY; cY += arcState.startPoint.y;
DrawItem->m_Pos.x = cX; DrawItem->m_Pos.x = cX;
DrawItem->m_Pos.y = cY; DrawItem->m_Pos.y = cY;
dx = ArcStartX - DrawItem->m_Pos.x; dx = arcState.startPoint.x - DrawItem->m_Pos.x;
dy = ArcStartY - DrawItem->m_Pos.y; dy = arcState.startPoint.y - DrawItem->m_Pos.y;
DrawItem->m_Radius = (int) sqrt( ( (double) dx * dx ) + DrawItem->m_Radius = (int) sqrt( ( (double) dx * dx ) +
( (double) dy * dy ) ); ( (double) dy * dy ) );
DrawItem->m_t1 = (int) ( atan2( (double) dy, (double) dx ) * 1800 / M_PI ); DrawItem->m_t1 = (int) ( atan2( (double) dy, (double) dx ) * 1800 / M_PI );
dx = ArcEndX - DrawItem->m_Pos.x; dx = arcState.endPoint.x - DrawItem->m_Pos.x;
dy = ArcEndY - DrawItem->m_Pos.y; dy = arcState.endPoint.y - DrawItem->m_Pos.y;
DrawItem->m_t2 = (int) ( atan2( (double) dy, (double) dx ) * 1800 / M_PI ); DrawItem->m_t2 = (int) ( atan2( (double) dy, (double) dx ) * 1800 / M_PI );
DrawItem->m_ArcStart.x = ArcStartX; DrawItem->m_ArcStart.x = arcState.startPoint.x;
DrawItem->m_ArcStart.y = ArcStartY; DrawItem->m_ArcStart.y = arcState.startPoint.y;
DrawItem->m_ArcEnd.x = ArcEndX; DrawItem->m_ArcEnd.x = arcState.endPoint.x;
DrawItem->m_ArcEnd.y = ArcEndY; DrawItem->m_ArcEnd.y = arcState.endPoint.y;
NORMALIZE_ANGLE( DrawItem->m_t1 ); NORMALIZE_ANGLE( DrawItem->m_t1 );
NORMALIZE_ANGLE( DrawItem->m_t2 ); // angles = 0 .. 3600 NORMALIZE_ANGLE( DrawItem->m_t2 ); // angles = 0 .. 3600
...@@ -654,6 +1061,42 @@ static void ComputeArc( LIB_ARC* DrawItem, wxPoint ArcCentre ) ...@@ -654,6 +1061,42 @@ static void ComputeArc( LIB_ARC* DrawItem, wxPoint ArcCentre )
} }
//! @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 * Used for deleting last entered segment while creating a Polyline
*/ */
......
...@@ -22,6 +22,36 @@ int ArcTangente( int dy, int dx ); ...@@ -22,6 +22,36 @@ int ArcTangente( int dy, int dx );
bool DistanceTest( int seuil, int dx, int dy, int spot_cX, int spot_cY ); bool DistanceTest( int seuil, int dx, int dy, int spot_cX, int spot_cY );
//! @brief Compute the distance between a line and a reference point
//! Reference: http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html
//! @param linePointA Point on line
//! @param linePointB Point on line
//! @param referencePoint Reference point
double DistanceLinePoint(wxPoint linePointA, wxPoint linePointB, wxPoint referencePoint);
//! @brief Euclidean norm of a 2D vector
//! @param vector Two-dimensional vector
//! @return Euclidean norm of the vector
double EuclideanNorm(wxPoint vector);
//! @brief Vector between two points
//! @param startPoint The start point
//! @param endPoint The end point
//! @return Vector between the points
wxPoint TwoPointVector(wxPoint startPoint, wxPoint endPoint);
//! @brief Test, if two points are near each other
//! @param pointA First point
//! @param pointB Second point
//! @param threshold The maximum distance
//! @return True or false
bool HitTestPoints(wxPoint pointA, wxPoint pointB, double threshold);
//! @brief Determine the cross product
//! @param vectorA Two-dimensional vector
//! @param vectorB Two-dimensional vector
int CrossProduct(wxPoint vectorA, wxPoint vectorB);
/** Function TestSegmentHit /** Function TestSegmentHit
* test for hit on line segment * test for hit on line segment
...@@ -34,6 +64,8 @@ bool DistanceTest( int seuil, int dx, int dy, int spot_cX, int spot_cY ); ...@@ -34,6 +64,8 @@ bool DistanceTest( int seuil, int dx, int dy, int spot_cX, int spot_cY );
bool TestSegmentHit( wxPoint aRefPoint, wxPoint aStart, wxPoint aEnd, bool TestSegmentHit( wxPoint aRefPoint, wxPoint aStart, wxPoint aEnd,
int aDist ); int aDist );
/*******************/ /*******************/
/* Macro NEW_COORD */ /* Macro NEW_COORD */
/*******************/ /*******************/
......
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