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
build_BOM.cpp
busentry.cpp
bus-wire-junction.cpp
class_BodyItem_Text.cpp
class_drawsheet.cpp
class_drawsheetpath.cpp
class_drc_erc_item.cpp
class_hierarchical_PIN_sheet.cpp
class_libentry.cpp
class_libentry_fields.cpp
class_library.cpp
class_marker_sch.cpp
class_netlist_object.cpp
......@@ -77,7 +75,6 @@ set(EESCHEMA_SRCS
edit_component_in_schematic.cpp
edit_label.cpp
eelayer.cpp
eelibs_draw_components.cpp
eelibs_read_libraryfiles.cpp
eeredraw.cpp
eeschema.cpp
......@@ -101,8 +98,10 @@ set(EESCHEMA_SRCS
lib_circle.cpp
lib_draw_item.cpp
lib_export.cpp
lib_field.cpp
lib_polyline.cpp
lib_rectangle.cpp
lib_text.cpp
libfield.cpp
load_one_schematic_file.cpp
locate.cpp
......@@ -135,6 +134,7 @@ set(EESCHEMA_SRCS
tool_lib.cpp
tool_sch.cpp
tool_viewlib.cpp
transform.cpp
viewlib_frame.cpp
viewlibs.cpp)
......
......@@ -906,7 +906,8 @@ static LIB_PIN* GetNextPinPosition( SCH_COMPONENT* aDrawLibItem,
bool aSearchFirst )
{
static LIB_COMPONENT* Entry;
static int Multi, convert, TransMat[2][2];
static int Multi, convert;
TRANSFORM transform;
static wxPoint CmpPosition;
static LIB_PIN* Pin;
......@@ -921,7 +922,7 @@ static LIB_PIN* GetNextPinPosition( SCH_COMPONENT* aDrawLibItem,
Multi = aDrawLibItem->m_Multi;
convert = aDrawLibItem->m_Convert;
CmpPosition = aDrawLibItem->m_Pos;
memcpy( TransMat, aDrawLibItem->m_Transform, sizeof(TransMat) );
transform = aDrawLibItem->m_Transform;
}
else
Pin = Entry->GetNextPin( Pin );
......@@ -938,7 +939,7 @@ static LIB_PIN* GetNextPinPosition( SCH_COMPONENT* aDrawLibItem,
/* 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;
}
......
......@@ -16,8 +16,7 @@
#include "libeditframe.h"
static void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC,
bool erase );
static void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
/*
......@@ -102,8 +101,8 @@ int WinEDA_LibeditFrame::HandleBlockEnd( wxDC* DC )
case BLOCK_COPY: /* Copy */
if ( m_component )
ItemCount = m_component->SelectItems( GetScreen()->m_BlockLocate,
m_unit, m_convert,
g_EditPinByPinIsOn );
m_unit, m_convert,
g_EditPinByPinIsOn );
if( ItemCount )
{
MustDoPlace = 1;
......@@ -127,8 +126,8 @@ int WinEDA_LibeditFrame::HandleBlockEnd( wxDC* DC )
case BLOCK_DELETE: /* Delete */
if ( m_component )
ItemCount = m_component->SelectItems( GetScreen()->m_BlockLocate,
m_unit, m_convert,
g_EditPinByPinIsOn );
m_unit, m_convert,
g_EditPinByPinIsOn );
if( ItemCount )
SaveCopyInUndoList( m_component );
if ( m_component )
......@@ -146,8 +145,8 @@ int WinEDA_LibeditFrame::HandleBlockEnd( wxDC* DC )
case BLOCK_MIRROR_Y:
if ( m_component )
ItemCount = m_component->SelectItems( GetScreen()->m_BlockLocate,
m_unit, m_convert,
g_EditPinByPinIsOn );
m_unit, m_convert,
g_EditPinByPinIsOn );
if( ItemCount )
SaveCopyInUndoList( m_component );
pt = GetScreen()->m_BlockLocate.Centre();
......@@ -169,7 +168,7 @@ int WinEDA_LibeditFrame::HandleBlockEnd( wxDC* DC )
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 )
m_component->ClearSelectedItems();
......@@ -179,8 +178,7 @@ int WinEDA_LibeditFrame::HandleBlockEnd( wxDC* DC )
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
GetScreen()->SetCurItem( NULL );
SetToolID( m_ID_current_state, DrawPanel->m_PanelDefaultCursor,
wxEmptyString );
SetToolID( m_ID_current_state, DrawPanel->m_PanelDefaultCursor, wxEmptyString );
DrawPanel->Refresh( TRUE );
}
......@@ -269,8 +267,7 @@ void WinEDA_LibeditFrame::HandleBlockPlace( wxDC* DC )
GetScreen()->SetCurItem( NULL );
DrawPanel->Refresh( TRUE );
SetToolID( m_ID_current_state, DrawPanel->m_PanelDefaultCursor,
wxEmptyString );
SetToolID( m_ID_current_state, DrawPanel->m_PanelDefaultCursor, wxEmptyString );
}
......@@ -298,25 +295,19 @@ void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
if( erase )
{
PtBlock->Draw( panel, DC, PtBlock->m_MoveVector, g_XorMode,
PtBlock->m_Color );
PtBlock->Draw( panel, DC, PtBlock->m_MoveVector, g_XorMode, PtBlock->m_Color );
component->Draw( panel, DC, PtBlock->m_MoveVector, unit, convert,
g_XorMode, -1, DefaultTransformMatrix,
true, true, true );
g_XorMode, -1, DefaultTransform, true, true, true );
}
/* Repaint new view */
PtBlock->m_MoveVector.x =
screen->m_Curseur.x - PtBlock->m_BlockLastCursorPosition.x;
PtBlock->m_MoveVector.y =
screen->m_Curseur.y - PtBlock->m_BlockLastCursorPosition.y;
PtBlock->m_MoveVector.x = screen->m_Curseur.x - PtBlock->m_BlockLastCursorPosition.x;
PtBlock->m_MoveVector.y = screen->m_Curseur.y - PtBlock->m_BlockLastCursorPosition.y;
GRSetDrawMode( DC, g_XorMode );
PtBlock->Draw( panel, DC, PtBlock->m_MoveVector, g_XorMode,
PtBlock->m_Color );
PtBlock->Draw( panel, DC, PtBlock->m_MoveVector, g_XorMode, PtBlock->m_Color );
component->Draw( panel, DC, PtBlock->m_MoveVector, unit, convert,
g_XorMode, -1, DefaultTransformMatrix,
true, true, true );
g_XorMode, -1, DefaultTransform, true, true, true );
}
......@@ -293,12 +293,9 @@ wxString LIB_COMPONENT::ReturnSubReference( int aUnit )
}
void LIB_COMPONENT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDc,
const wxPoint& aOffset, int aMulti,
int aConvert, int aDrawMode, int aColor,
const int aTransformMatrix[2][2],
bool aShowPinText, bool aDrawFields,
bool aOnlySelected )
void LIB_COMPONENT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDc, const wxPoint& aOffset, int aMulti,
int aConvert, int aDrawMode, int aColor, const TRANSFORM& aTransform,
bool aShowPinText, bool aDrawFields, bool aOnlySelected )
{
BASE_SCREEN* screen = aPanel->GetScreen();
......@@ -336,14 +333,12 @@ void LIB_COMPONENT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDc,
if( drawItem.Type() == COMPONENT_FIELD_DRAW_TYPE )
{
drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode,
(void*) NULL, aTransformMatrix );
drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode, NULL, aTransform );
}
// Now, draw only the background for items with
// m_Fill == FILLED_WITH_BG_BODYCOLOR:
drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode,
(void*) false, aTransformMatrix );
drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode, false, aTransform );
}
}
......@@ -368,19 +363,18 @@ void LIB_COMPONENT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDc,
if( drawItem.Type() == COMPONENT_PIN_DRAW_TYPE )
{
drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode,
(void*) aShowPinText, aTransformMatrix );
drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode, (void*) aShowPinText,
aTransform );
}
else if( drawItem.Type() == COMPONENT_FIELD_DRAW_TYPE )
{
drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode,
(void*) NULL, aTransformMatrix );
drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode, (void*) NULL, aTransform );
}
else
{
bool forceNoFill = drawItem.m_Fill == FILLED_WITH_BG_BODYCOLOR;
drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode,
(void*) forceNoFill, aTransformMatrix );
drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode, (void*) forceNoFill,
aTransform );
}
}
......@@ -409,7 +403,7 @@ void LIB_COMPONENT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDc,
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 );
......@@ -451,7 +445,7 @@ from component %s in library %s." ),
LIB_DRAW_ITEM_LIST::iterator i;
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++ )
{
......@@ -1383,30 +1377,33 @@ LIB_DRAW_ITEM* LIB_COMPONENT::LocateDrawItem( int aUnit, int aConvert,
* Otherwise NULL.
*/
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
* wxPoint& pt ) to search items.
* because this function uses DefaultTransformMatrix as orient/mirror matrix
* we temporary copy aTransMat in DefaultTransformMatrix
*/
LIB_DRAW_ITEM * item;
int matrix[2][2];
LIB_DRAW_ITEM* item;
TRANSFORM transform;
for ( int ii = 0; ii < 2; ii++ )
{
for ( int jj = 0; jj < 2; jj++ )
{
matrix[ii][jj] = aTransform[ii][jj];
EXCHG( matrix[ii][jj], DefaultTransformMatrix[ii][jj] );
transform = DefaultTransform;
DefaultTransform = aTransform;
}
}
item = LocateDrawItem( aUnit, aConvert, aType, aPoint );
//Restore matrix
for ( int ii = 0; ii < 2; ii++ )
{
for ( int jj = 0; jj < 2; jj++ )
{
EXCHG( matrix[ii][jj], DefaultTransformMatrix[ii][jj] );
DefaultTransform = transform;
}
}
......
......@@ -6,7 +6,7 @@
#define CLASS_LIBENTRY_H
#include "lib_draw_item.h"
#include "class_libentry_fields.h"
#include "lib_field.h"
#include <map>
......@@ -14,6 +14,7 @@
class CMP_LIBRARY;
class LIB_ALIAS;
/**
* LIB_ALIAS map sorting.
*/
......@@ -312,7 +313,7 @@ public:
*/
void Draw( WinEDA_DrawPanel* aPanel, wxDC* aDc, const wxPoint& aOffset,
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 aOnlySelected = false );
......@@ -325,7 +326,7 @@ public:
* @param aTransform - Component plot transform matrix.
*/
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.
......@@ -493,7 +494,7 @@ public:
* @return The draw object if found. Otherwise NULL.
*/
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.
......
......@@ -17,6 +17,7 @@
#include "libeditframe.h"
#include "class_libentry.h"
#include "class_pin.h"
#include "transform.h"
#include "bitmaps.h"
......@@ -536,7 +537,7 @@ bool LIB_PIN::HitTest( const wxPoint& aRefPos )
if( mindist < 3 )
mindist = 3; // = 3 mils
return HitTest( aRefPos, mindist, DefaultTransformMatrix );
return HitTest( aRefPos, mindist, DefaultTransform );
}
/** Function HitTest
......@@ -545,11 +546,10 @@ bool LIB_PIN::HitTest( const wxPoint& aRefPos )
* @param aThreshold = max distance to a segment
* @param aTransMat = the transform matrix
*/
bool LIB_PIN::HitTest( wxPoint aRefPos, int aThreshold,
const int aTransMat[2][2] )
bool LIB_PIN::HitTest( wxPoint aRefPos, int aThreshold, const TRANSFORM& aTransform )
{
wxPoint pinPos = TransformCoordinate( aTransMat, m_Pos );
wxPoint pinEnd = TransformCoordinate( aTransMat, ReturnPinEndPoint() );
wxPoint pinPos = aTransform.TransformCoordinate( m_Pos );
wxPoint pinEnd = aTransform.TransformCoordinate( ReturnPinEndPoint() );
return TestSegmentHit( aRefPos, pinPos, pinEnd, aThreshold );
}
......@@ -791,18 +791,17 @@ int LIB_PIN::GetPenSize()
}
void LIB_PIN::Draw( WinEDA_DrawPanel* aPanel,
wxDC* aDC,
const wxPoint& aOffset,
int aColor,
int aDrawMode,
void* aData,
const int aTransformMatrix[2][2] )
void LIB_PIN::drawGraphic( WinEDA_DrawPanel* aPanel,
wxDC* aDC,
const wxPoint& aOffset,
int aColor,
int aDrawMode,
void* aData,
const TRANSFORM& aTransform )
{
// Invisible pins are only drawn on request. In libedit they are drawn
// in g_InvisibleItemColor because we must see them.
WinEDA_SchematicFrame* frame =
(WinEDA_SchematicFrame*) wxGetApp().GetTopWindow();
WinEDA_SchematicFrame* frame = (WinEDA_SchematicFrame*) wxGetApp().GetTopWindow();
if( ( m_Attributs & PINNOTDRAW ) )
{
......@@ -819,10 +818,10 @@ void LIB_PIN::Draw( WinEDA_DrawPanel* aPanel,
DrawPinText = false;
/* Calculate pin orient taking in account the component orientation. */
int orient = ReturnPinDrawOrient( aTransformMatrix );
int orient = ReturnPinDrawOrient( aTransform );
/* 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 */
DrawPinSymbol( aPanel, aDC, pos1, orient, aDrawMode, aColor );
......@@ -1476,7 +1475,7 @@ wxPoint LIB_PIN::ReturnPinEndPoint()
* according to its orientation and the matrix transform (rot, mirror) TransMat
* @param TransMat = transform matrix
*/
int LIB_PIN::ReturnPinDrawOrient( const int TransMat[2][2] )
int LIB_PIN::ReturnPinDrawOrient( const TRANSFORM& aTransform )
{
int orient;
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] )
}
// = pos of end point, according to the component orientation
end = TransformCoordinate( TransMat, end );
end = aTransform.TransformCoordinate( end );
orient = PIN_UP;
if( end.x == 0 )
{
......@@ -1653,14 +1652,14 @@ void LIB_PIN::DoMirrorHorizontal( const wxPoint& center )
void LIB_PIN::DoPlot( PLOTTER* plotter, const wxPoint& offset, bool fill,
const int transform[2][2] )
const TRANSFORM& aTransform )
{
if( m_Attributs & PINNOTDRAW )
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() );
PlotPinSymbol( plotter, pos, m_PinLen, orient, m_PinShape );
......
......@@ -9,8 +9,8 @@
#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 PART_NAME_LEN 15 /* Maximum length of part name. */
......@@ -80,6 +80,12 @@ enum DrawPinOrient {
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:
int m_PinLen; /* Pin length */
int m_Orient; /* Pin orientation (Up, Down, Left, Right) */
......@@ -106,7 +112,7 @@ public:
int m_Width; /* Line width */
public:
LIB_PIN(LIB_COMPONENT * aParent);
LIB_PIN( LIB_COMPONENT * aParent );
LIB_PIN( const LIB_PIN& aPin );
~LIB_PIN() { }
......@@ -148,13 +154,13 @@ public:
* @param aTransMat - the transform matrix
* @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 EDA_Rect GetBoundingBox();
wxPoint ReturnPinEndPoint();
int ReturnPinDrawOrient( const int TransMat[2][2] );
int ReturnPinDrawOrient( const TRANSFORM& aTransform );
/**
* Fill a string buffer with pin number.
......@@ -194,7 +200,7 @@ public:
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
* by EnableEditMode().
......@@ -323,9 +329,6 @@ public:
*/
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,
int aOrientation, int aDrawMode, int aColor = -1 );
......@@ -438,7 +441,7 @@ protected:
virtual wxPoint DoGetPosition() { return m_Pos; }
virtual void DoMirrorHorizontal( const wxPoint& aCenter );
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 void DoSetWidth( int aWidth ) { m_Width = aWidth; }
};
......
......@@ -98,7 +98,7 @@ void SCH_FIELD::Draw( WinEDA_DrawPanel* panel, wxDC* DC,
/* Calculate the text orientation, according to the component
* orientation/mirror */
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 )
orient = TEXT_ORIENT_VERT;
......@@ -245,11 +245,11 @@ EDA_Rect SCH_FIELD::GetBoundaryBox() const
hjustify = m_HJustify;
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
* orientation/mirror */
if( parentComponent->m_Transform[0][1] )
if( parentComponent->m_Transform.y1 )
{
if( orient == TEXT_ORIENT_HORIZ )
orient = TEXT_ORIENT_VERT;
......@@ -259,20 +259,20 @@ EDA_Rect SCH_FIELD::GetBoundaryBox() const
/* Calculate the text justification, according to the component
* orientation/mirror */
if( parentComponent->m_Transform[0][1] )
if( parentComponent->m_Transform.y1 )
{
/* is it mirrored (for text justify)*/
EXCHG( hjustify, vjustify );
if( parentComponent->m_Transform[1][0] < 0 )
if( parentComponent->m_Transform.x2 < 0 )
NEGATE( vjustify );
if( parentComponent->m_Transform[0][1] > 0 )
if( parentComponent->m_Transform.y1 > 0 )
NEGATE( hjustify );
}
else /* component horizontal: is it mirrored (for text justify)*/
{
if( parentComponent->m_Transform[0][0] < 0 )
if( parentComponent->m_Transform.x1 < 0 )
NEGATE( hjustify );
if( parentComponent->m_Transform[1][1] > 0 )
if( parentComponent->m_Transform.y2 > 0 )
NEGATE( vjustify );
}
......
......@@ -151,10 +151,7 @@ void SCH_COMPONENT::Init( const wxPoint& pos )
m_Convert = 0; // De Morgan Handling
// The rotation/mirror transformation matrix. pos normal
m_Transform[0][0] = 1;
m_Transform[0][1] = 0;
m_Transform[1][0] = 0;
m_Transform[1][1] = -1;
m_Transform = TRANSFORM();
// construct only the mandatory fields, which are the first 4 only.
for( int i = 0; i < MANDATORY_FIELDS; ++i )
......@@ -578,10 +575,10 @@ EDA_Rect SCH_COMPONENT::GetBoundaryBox() const
}
/* Compute the real Boundary box (rotated, mirrored ...)*/
int x1 = m_Transform[0][0] *x0 + m_Transform[0][1] *y0;
int y1 = m_Transform[1][0] *x0 + m_Transform[1][1] *y0;
int x2 = m_Transform[0][0] *xm + m_Transform[0][1] *ym;
int y2 = m_Transform[1][0] *xm + m_Transform[1][1] *ym;
int x1 = m_Transform.x1 * x0 + m_Transform.y1 * y0;
int y1 = m_Transform.x2 * x0 + m_Transform.y2 * y0;
int x2 = m_Transform.x1 * xm + m_Transform.y1 * ym;
int y2 = m_Transform.x2 * xm + m_Transform.y2 * ym;
// H and W must be > 0:
if( x2 < x1 )
......@@ -608,10 +605,10 @@ void SCH_COMPONENT::SwapData( SCH_COMPONENT* copyitem )
EXCHG( m_Pos, copyitem->m_Pos );
EXCHG( m_Multi, copyitem->m_Multi );
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] );
EXCHG( m_Transform[1][0], copyitem->m_Transform[1][0] );
EXCHG( m_Transform[1][1], copyitem->m_Transform[1][1] );
TRANSFORM tmp = m_Transform;
m_Transform = copyitem->m_Transform;
copyitem->m_Transform = tmp;
m_Fields.swap( copyitem->m_Fields ); // std::vector's swap()
......@@ -727,44 +724,44 @@ void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheet )
/*****************************************************************/
void SCH_COMPONENT::SetOrientation( int aOrientation )
{
int TempMat[2][2];
bool Transform = FALSE;
TRANSFORM temp = TRANSFORM();
bool Transform = false;
switch( aOrientation )
{
case CMP_ORIENT_0:
case CMP_NORMAL: /* Position Initiale */
m_Transform[0][0] = 1;
m_Transform[1][1] = -1;
m_Transform[1][0] = m_Transform[0][1] = 0;
m_Transform.x1 = 1;
m_Transform.y2 = -1;
m_Transform.x2 = m_Transform.y1 = 0;
break;
case CMP_ROTATE_CLOCKWISE: /* Rotate + */
TempMat[0][0] = TempMat[1][1] = 0;
TempMat[0][1] = 1;
TempMat[1][0] = -1;
Transform = TRUE;
temp.x1 = temp.y2 = 0;
temp.y1 = 1;
temp.x2 = -1;
Transform = true;
break;
case CMP_ROTATE_COUNTERCLOCKWISE: /* Rotate - */
TempMat[0][0] = TempMat[1][1] = 0;
TempMat[0][1] = -1;
TempMat[1][0] = 1;
Transform = TRUE;
temp.x1 = temp.y2 = 0;
temp.y1 = -1;
temp.x2 = 1;
Transform = true;
break;
case CMP_MIRROR_Y: /* MirrorY */
TempMat[0][0] = -1;
TempMat[1][1] = 1;
TempMat[0][1] = TempMat[1][0] = 0;
Transform = TRUE;
temp.x1 = -1;
temp.y2 = 1;
temp.y1 = temp.x2 = 0;
Transform = true;
break;
case CMP_MIRROR_X: /* MirrorX */
TempMat[0][0] = 1;
TempMat[1][1] = -1;
TempMat[0][1] = TempMat[1][0] = 0;
Transform = TRUE;
temp.x1 = 1;
temp.y2 = -1;
temp.y1 = temp.x2 = 0;
Transform = TRUE;
break;
case CMP_ORIENT_90:
......@@ -841,24 +838,13 @@ void SCH_COMPONENT::SetOrientation( int aOrientation )
* have:
* transform coord = old_m_Transform * coord * TempMat
*/
int NewMatrix[2][2];
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];
TRANSFORM newTransform;
NewMatrix[1][1] = m_Transform[0][1] *TempMat[1][0] +
m_Transform[1][1] *TempMat[1][1];
m_Transform[0][0] = NewMatrix[0][0];
m_Transform[0][1] = NewMatrix[0][1];
m_Transform[1][0] = NewMatrix[1][0];
m_Transform[1][1] = NewMatrix[1][1];
newTransform.x1 = m_Transform.x1 * temp.x1 + m_Transform.x2 * temp.y1;
newTransform.y1 = m_Transform.y1 * temp.x1 + m_Transform.y2 * temp.y1;
newTransform.x2 = m_Transform.x1 * temp.x2 + m_Transform.x2 * temp.y2;
newTransform.y2 = m_Transform.y1 * temp.x2 + m_Transform.y2 * temp.y2;
m_Transform = newTransform;
}
}
......@@ -879,7 +865,7 @@ void SCH_COMPONENT::SetOrientation( int aOrientation )
int SCH_COMPONENT::GetOrientation()
{
int type_rotate = CMP_ORIENT_0;
int ComponentMatOrient[2][2];
TRANSFORM transform;
int ii;
#define ROTATE_VALUES_COUNT 12
......@@ -896,20 +882,21 @@ int SCH_COMPONENT::GetOrientation()
};
// Try to find the current transform option:
memcpy( ComponentMatOrient, m_Transform, sizeof( ComponentMatOrient ) );
transform = m_Transform;
for( ii = 0; ii < ROTATE_VALUES_COUNT; ii++ )
{
type_rotate = rotate_value[ii];
SetOrientation( type_rotate );
if( memcmp( ComponentMatOrient, m_Transform,
sizeof(ComponentMatOrient) ) == 0 )
if( transform == m_Transform )
return type_rotate;
}
// Error: orientation not found in list (should not happen)
wxMessageBox( wxT( "Component orientation matrix internal error" ) );
memcpy( m_Transform, ComponentMatOrient, sizeof( ComponentMatOrient ) );
m_Transform = transform;
return CMP_NORMAL;
}
......@@ -921,11 +908,7 @@ int SCH_COMPONENT::GetOrientation()
*/
wxPoint SCH_COMPONENT::GetScreenCoord( const wxPoint& coord )
{
wxPoint screenpos;
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;
return m_Transform.TransformCoordinate( coord );
}
......@@ -1100,8 +1083,7 @@ bool SCH_COMPONENT::Save( FILE* f ) const
return false;
if( fprintf( f, "\t%-4d %-4d %-4d %-4d\n",
m_Transform[0][0], m_Transform[0][1],
m_Transform[1][0], m_Transform[1][1] ) == EOF )
m_Transform.x1, m_Transform.y1, m_Transform.x2, m_Transform.y2 ) == EOF )
return false;
if( fprintf( f, "$EndComp\n" ) == EOF )
......@@ -1292,7 +1274,7 @@ bool SCH_COMPONENT::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxP
if( aFindLocation )
{
wxPoint pinpos = pin->m_Pos;
pinpos = TransformCoordinate( m_Transform, pinpos );
pinpos = m_Transform.TransformCoordinate( pinpos );
*aFindLocation = pinpos + m_Pos;
}
return true;
......
......@@ -8,6 +8,7 @@
#include "class_sch_screen.h"
#include "class_sch_cmp_field.h"
#include "transform.h"
class SCH_SHEET_PATH;
......@@ -62,8 +63,8 @@ public:
int m_Convert; /* Handle multiple shape (for instance
* De Morgan conversion) */
int m_Transform[2][2]; /* The rotation/mirror transformation
* matrix. */
TRANSFORM m_Transform; /* The rotation/mirror transformation
* matrix. */
private:
......
......@@ -147,8 +147,7 @@ LIB_PIN* WinEDA_SchematicFrame::LocatePinEnd( SCH_ITEM* DrawList,
// and in schematic Y axis is top to bottom
else // calculate the pin position in schematic
pinpos = TransformCoordinate( DrawLibItem->m_Transform, pinpos )
+ DrawLibItem->m_Pos;
pinpos = DrawLibItem->m_Transform.TransformCoordinate( pinpos ) + DrawLibItem->m_Pos;
if( pos == pinpos )
return Pin;
......@@ -261,8 +260,7 @@ wxPoint ReturnPinPhysicalPosition( LIB_PIN* Pin, SCH_COMPONENT* DrawLibItem )
NEGATE( PinPos.y );
else
PinPos = TransformCoordinate( DrawLibItem->m_Transform,
Pin->m_Pos ) + DrawLibItem->m_Pos;
PinPos = DrawLibItem->m_Transform.TransformCoordinate( Pin->m_Pos ) + DrawLibItem->m_Pos;
return PinPos;
}
......
......@@ -51,10 +51,10 @@ void WinEDA_SchematicFrame::StartMoveCmpField( SCH_FIELD* aField, wxDC* DC )
// under some circumstances, but that inversion is not preserved by all
// combinations of mirroring and rotation. The following clause is true
// 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 );
newpos = TransformCoordinate( comp->m_Transform, newpos ) + pos;
newpos = comp->m_Transform.TransformCoordinate( newpos ) + pos;
DrawPanel->CursorOff( DC );
GetScreen()->m_Curseur = newpos;
......@@ -184,7 +184,6 @@ modified!\nYou must create a new power" ) );
static void MoveCmpField( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
{
wxPoint pos;
int x1, y1;
int fieldNdx;
WinEDA_SchematicFrame* frame = (WinEDA_SchematicFrame*) panel->GetParent();
......@@ -205,13 +204,9 @@ static void MoveCmpField( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
pos = ( (SCH_COMPONENT*) currentField->GetParent() )->m_Pos;
/* Positions are calculated by the transpose matrix, Rotating mirror. */
x1 = panel->GetScreen()->m_Curseur.x - pos.x;
y1 = panel->GetScreen()->m_Curseur.y - pos.y;
wxPoint pt( panel->GetScreen()->m_Curseur - pos );
currentField->m_Pos.x = pos.x + component->m_Transform[0][0] * x1 +
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->m_Pos = pos + component->m_Transform.TransformCoordinate( pt );
currentField->Draw( panel, DC, wxPoint( 0, 0 ), g_XorMode );
}
......
......@@ -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;
if ( ( DrawItem == NULL )
|| ( DrawItem->Type() != COMPONENT_GRAPHIC_TEXT_DRAW_TYPE ) )
if ( ( DrawItem == NULL ) || ( DrawItem->Type() != COMPONENT_GRAPHIC_TEXT_DRAW_TYPE ) )
return;
/* Deleting old text. */
if( DC)
DrawItem->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, DrawMode, NULL,
DefaultTransformMatrix );
if( DC )
DrawItem->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, DrawMode, NULL, DefaultTransform );
Dialog_BodyGraphicText_Properties * frame =
new Dialog_BodyGraphicText_Properties( this,
(LIB_TEXT*) DrawItem );
new Dialog_BodyGraphicText_Properties( this, (LIB_TEXT*) DrawItem );
frame->ShowModal();
frame->Destroy();
OnModify( );
OnModify();
/* Display new text. */
if( DC )
......@@ -249,42 +246,6 @@ void WinEDA_LibeditFrame::EditSymbolText(wxDC* DC, LIB_DRAW_ITEM* DrawItem)
if ( ( DrawItem->m_Flags & IS_MOVED ) == 0 )
DrawMode = GR_DEFAULT_DRAWMODE;
DrawItem->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, DrawMode, NULL,
DefaultTransformMatrix );
DrawItem->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, DrawMode, NULL, DefaultTransform );
}
}
/****************************************************/
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 @@
#include "protos.h"
#include "hotkeys.h"
#include "transform.h"
#include <wx/snglinst.h>
......@@ -83,7 +85,7 @@ int g_ItemSelectetColor = BROWN;
// in eeschema
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
}
wxPoint delta;
pos -= Component->m_Pos;
delta = TransformCoordinate( Component->m_Transform, pos );
delta = Component->m_Transform.TransformCoordinate( pos );
pos = delta + Component->m_Pos;
wxPoint old_cursor_position = sheet->LastScreen()->m_Curseur;
......
......@@ -23,8 +23,8 @@
static void ShowWhileMoving( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
static void ExitPlaceCmp( WinEDA_DrawPanel* Panel, wxDC* DC );
static int OldTransMat[2][2];
static wxPoint OldPos;
static TRANSFORM OldTransform;
static wxPoint OldPos;
wxString WinEDA_SchematicFrame::SelectFromLibBrowser( void )
......@@ -294,7 +294,7 @@ static void ExitPlaceCmp( WinEDA_DrawPanel* Panel, wxDC* DC )
{
wxPoint move_vector = OldPos - Component->m_Pos;
Component->Move( move_vector );
memcpy( Component->m_Transform, OldTransMat, sizeof(OldTransMat) );
Component->m_Transform = OldTransform;
Component->m_Flags = 0;
}
......@@ -401,8 +401,7 @@ void WinEDA_SchematicFrame::ConvertPart( SCH_COMPONENT* DrawComponent,
}
void WinEDA_SchematicFrame::StartMovePart( SCH_COMPONENT* Component,
wxDC* DC )
void WinEDA_SchematicFrame::StartMovePart( SCH_COMPONENT* Component, wxDC* DC )
{
if( Component == NULL )
return;
......@@ -426,7 +425,7 @@ void WinEDA_SchematicFrame::StartMovePart( SCH_COMPONENT* Component,
DrawPanel->ForceCloseManageCurseur = ExitPlaceCmp;
GetScreen()->SetCurItem( Component );
OldPos = Component->m_Pos;
memcpy( OldTransMat, Component->m_Transform, sizeof(OldTransMat) );
OldTransform = Component->m_Transform;
#if 1
......
......@@ -88,16 +88,13 @@ static Ki_HotkeyInfo HkResetLocalCoord( wxT( "Reset local coord." ),
HK_RESET_LOCAL_COORD, ' ' );
/* Undo */
static Ki_HotkeyInfo HkUndo( wxT( "Undo" ), HK_UNDO, GR_KB_CTRL + 'Z',
(int) wxID_UNDO );
static Ki_HotkeyInfo HkUndo( wxT( "Undo" ), HK_UNDO, GR_KB_CTRL + 'Z', (int) wxID_UNDO );
/* Redo */
#if !defined( __WXMAC__ )
static Ki_HotkeyInfo HkRedo( wxT( "Redo" ), HK_REDO, GR_KB_CTRL + 'Y',
(int) wxID_REDO );
static Ki_HotkeyInfo HkRedo( wxT( "Redo" ), HK_REDO, GR_KB_CTRL + 'Y', (int) wxID_REDO );
#else
static Ki_HotkeyInfo HkRedo( wxT( "Redo" ), HK_REDO,
GR_KB_SHIFT + GR_KB_CTRL + 'Z',
static Ki_HotkeyInfo HkRedo( wxT( "Redo" ), HK_REDO, GR_KB_SHIFT + GR_KB_CTRL + 'Z',
(int) wxID_REDO );
#endif
......@@ -131,27 +128,21 @@ static Ki_HotkeyInfo HkCopyComponentOrText( wxT( "Copy Component or Label" ),
HK_COPY_COMPONENT_OR_LABEL, 'C',
ID_POPUP_SCH_COPY_ITEM );
static Ki_HotkeyInfo HkDrag( wxT( "Drag Schematic Item" ),
HK_DRAG, 'G',
static Ki_HotkeyInfo HkDrag( wxT( "Drag Schematic Item" ), HK_DRAG, 'G',
ID_POPUP_SCH_DRAG_CMP_REQUEST );
static Ki_HotkeyInfo HkMove2Drag( wxT( "Switch move block to drag block" ),
HK_MOVEBLOCK_TO_DRAGBLOCK, '\t' );
static Ki_HotkeyInfo HkInsert( wxT( "Repeat Last Item" ), HK_REPEAT_LAST,
WXK_INSERT );
static Ki_HotkeyInfo HkInsert( wxT( "Repeat Last Item" ), HK_REPEAT_LAST, WXK_INSERT );
static Ki_HotkeyInfo HkDelete( wxT( "Delete Item" ), HK_DELETE, WXK_DELETE );
static Ki_HotkeyInfo HkFindItem( wxT( "Find Item" ), HK_FIND_ITEM, 'F'
+ GR_KB_CTRL );
static Ki_HotkeyInfo HkFindNextItem( wxT( "Find Next Item" ), HK_FIND_NEXT_ITEM,
WXK_F5 );
static Ki_HotkeyInfo HkFindItem( wxT( "Find Item" ), HK_FIND_ITEM, 'F' + GR_KB_CTRL );
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,
WXK_F5 + GR_KB_SHIFT );
// Special keys for library editor:
static Ki_HotkeyInfo HkCreatePin( wxT( "Create Pin" ),
HK_LIBEDIT_CREATE_PIN, 'P' );
static Ki_HotkeyInfo HkInsertPin( wxT( "Repeat Pin" ), HK_REPEAT_LAST,
WXK_INSERT );
static Ki_HotkeyInfo HkCreatePin( wxT( "Create Pin" ), HK_LIBEDIT_CREATE_PIN, 'P' );
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' );
......@@ -256,8 +247,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
cmd.SetEventObject( this );
bool ItemInEdit = GetScreen()->GetCurItem()
&& GetScreen()->GetCurItem()->m_Flags;
bool ItemInEdit = GetScreen()->GetCurItem()&& GetScreen()->GetCurItem()->m_Flags;
bool RefreshToolBar = FALSE;
SCH_SCREEN* screen = GetScreen();
......@@ -272,8 +262,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
hotkey += 'A' - 'a';
// Search command from key :
Ki_HotkeyInfo* HK_Descr = GetDescriptorFromHotkey( hotkey,
s_Common_Hotkey_List );
Ki_HotkeyInfo* HK_Descr = GetDescriptorFromHotkey( hotkey, s_Common_Hotkey_List );
if( HK_Descr == NULL )
HK_Descr = GetDescriptorFromHotkey( hotkey, s_Schematic_Hotkey_List );
if( HK_Descr == NULL )
......@@ -322,8 +311,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
case HK_REDO:
if( !ItemInEdit )
{
wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED,
HK_Descr->m_IdMenuEvent );
wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, HK_Descr->m_IdMenuEvent );
wxPostEvent( this, event );
}
break;
......@@ -383,8 +371,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
{
// switch to m_ID_current_state = ID_COMPONENT_BUTT;
if( m_ID_current_state != ID_COMPONENT_BUTT )
SetToolID( ID_COMPONENT_BUTT, wxCURSOR_PENCIL,
_( "Add Component" ) );
SetToolID( ID_COMPONENT_BUTT, wxCURSOR_PENCIL, _( "Add Component" ) );
OnLeftClick( DC, MousePos );
}
break;
......@@ -428,8 +415,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
if( !ItemInEdit )
{
if( m_ID_current_state != ID_NOCONN_BUTT )
SetToolID( ID_NOCONN_BUTT, wxCURSOR_PENCIL,
_( "Add \"NoNonnect\" Flags" ) );
SetToolID( ID_NOCONN_BUTT, wxCURSOR_PENCIL, _( "Add \"NoNonnect\" Flags" ) );
OnLeftClick( DC, MousePos );
}
break;
......@@ -439,7 +425,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
{
HandleBlockEndByPopUp(BLOCK_ROTATE, DC );
break;
}
}
if( DrawStruct == NULL )
{
// Find the schematic object to rotate under the cursor
......@@ -494,11 +480,11 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
break;
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 );
break;
}
}
if( DrawStruct == NULL )
DrawStruct = LocateSmallestComponent( (SCH_SCREEN*) GetScreen() );
if( DrawStruct )
......@@ -513,11 +499,11 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
break;
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 );
break;
}
}
if( DrawStruct == NULL )
DrawStruct = LocateSmallestComponent( GetScreen() );
if( DrawStruct )
......@@ -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
SCH_SHEET_PIN* slabel = LocateSheetLabel( (SCH_SHEET*) DrawStruct,
GetScreen()->m_Curseur );
GetScreen()->m_Curseur );
if( slabel )
DrawStruct = slabel;
}
......@@ -648,9 +634,8 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
break;
if( DrawStruct == NULL )
{
DrawStruct = PickStruct( GetScreen()->m_Curseur,
GetScreen(), LIBITEM | TEXTITEM |
LABELITEM | SHEETITEM );
DrawStruct = PickStruct( GetScreen()->m_Curseur, GetScreen(),
LIBITEM | TEXTITEM | LABELITEM | SHEETITEM );
if( DrawStruct == NULL )
break;
if( DrawStruct->Type() == TYPE_SCH_COMPONENT )
......@@ -721,8 +706,7 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
* under the mouse cursor
* Commands are case insensitive
*/
void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey,
EDA_BaseStruct* DrawStruct )
void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey, EDA_BaseStruct* DrawStruct )
{
wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
wxCommandEvent toolCmd( wxEVT_COMMAND_TOOL_CLICKED );
......@@ -730,8 +714,7 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey,
cmd.SetEventObject( this );
wxPoint MousePos = GetScreen()->m_MousePosition;
bool ItemInEdit = GetScreen()->GetCurItem()
&& GetScreen()->GetCurItem()->m_Flags;
bool ItemInEdit = GetScreen()->GetCurItem()&& GetScreen()->GetCurItem()->m_Flags;
if( hotkey == 0 )
return;
......@@ -740,8 +723,7 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey,
* with non ascii codes like function keys */
if( (hotkey >= 'a') && (hotkey <= 'z') )
hotkey += 'A' - 'a';
Ki_HotkeyInfo* HK_Descr = GetDescriptorFromHotkey( hotkey,
s_Common_Hotkey_List );
Ki_HotkeyInfo* HK_Descr = GetDescriptorFromHotkey( hotkey, s_Common_Hotkey_List );
if( HK_Descr == NULL )
HK_Descr = GetDescriptorFromHotkey( hotkey, s_LibEdit_Hotkey_List );
if( HK_Descr == NULL )
......@@ -843,7 +825,7 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey,
case HK_ROTATE:
m_drawItem = LocateItemUsingCursor();
if( m_drawItem )
if( m_drawItem && !m_drawItem->InEditMode() )
{
switch( m_drawItem->Type() )
{
......@@ -875,7 +857,7 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey,
case HK_DELETE:
m_drawItem = LocateItemUsingCursor();
if( m_drawItem )
if( m_drawItem && !m_drawItem->InEditMode() )
{
wxCommandEvent evt;
evt.SetId( ID_POPUP_LIBEDIT_DELETE_ITEM );
......@@ -886,7 +868,7 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey,
case HK_LIBEDIT_MOVE_GRAPHIC_ITEM:
m_drawItem = LocateItemUsingCursor();
if( m_drawItem )
if( m_drawItem && !m_drawItem->InEditMode() )
{
wxCommandEvent evt;
evt.SetId( ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST );
......@@ -897,7 +879,7 @@ void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey,
case HK_DRAG:
m_drawItem = LocateItemUsingCursor();
if( m_drawItem )
if( m_drawItem && !m_drawItem->InEditMode() )
{
wxCommandEvent evt;
evt.SetId( ID_POPUP_LIBEDIT_MODIFY_ITEM );
......
......@@ -12,17 +12,56 @@
#include "general.h"
#include "protos.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 )
{
m_Radius = 0;
m_t1 = 0;
m_t2 = 0;
m_Width = 0;
m_Fill = NO_FILL;
m_isFillable = true;
m_typeName = _( "Arc" );
m_Radius = 0;
m_t1 = 0;
m_t2 = 0;
m_Width = 0;
m_Fill = NO_FILL;
m_isFillable = true;
m_typeName = _( "Arc" );
m_editState = 0;
m_lastEditState = 0;
}
......@@ -130,7 +169,7 @@ bool LIB_ARC::HitTest( const wxPoint& aRefPoint )
if( mindist < MINIMUM_SELECTION_DISTANCE )
mindist = MINIMUM_SELECTION_DISTANCE;
return HitTest( aRefPoint, mindist, DefaultTransformMatrix );
return HitTest( aRefPoint, mindist, DefaultTransform );
}
/** Function HitTest
......@@ -140,8 +179,7 @@ bool LIB_ARC::HitTest( const wxPoint& aRefPoint )
* of a line)
* @param aTransMat = the transform matrix
*/
bool LIB_ARC::HitTest( wxPoint aReferencePoint, int aThreshold,
const int aTransformationMatrix[2][2] )
bool LIB_ARC::HitTest( wxPoint aReferencePoint, int aThreshold, const TRANSFORM& aTransform )
{
// TODO: use aTransMat to calculmates parameters
......@@ -149,7 +187,7 @@ bool LIB_ARC::HitTest( wxPoint aReferencePoint, int aThreshold,
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 )
return false;
......@@ -160,8 +198,8 @@ bool LIB_ARC::HitTest( wxPoint aReferencePoint, int aThreshold,
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 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
......@@ -172,7 +210,7 @@ bool LIB_ARC::HitTest( wxPoint aReferencePoint, int aThreshold,
// relative to the start point to end point vector lies
if( CrossProduct( startEndVector, startRelativePositionVector ) < 0 )
{
EXCHG(crossProductStart, crossProductEnd);
EXCHG( crossProductStart, crossProductEnd );
}
// When the cross products have a different sign, the point lies in sector
......@@ -265,15 +303,15 @@ void LIB_ARC::DoMirrorHorizontal( const wxPoint& aCenter )
void LIB_ARC::DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
const int aTransform[2][2] )
const TRANSFORM& aTransform )
{
wxASSERT( aPlotter != NULL );
int t1 = m_t1;
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 )
{
......@@ -295,12 +333,35 @@ int LIB_ARC::GetPenSize()
}
void LIB_ARC::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
const wxPoint& aOffset, int aColor, int aDrawMode,
void* aData, const int aTransformMatrix[2][2] )
void LIB_ARC::drawEditGraphics( EDA_Rect* aClipBox, wxDC* aDC, int aColor )
{
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 );
if( aColor < 0 ) // Used normal color or selected color
......@@ -309,14 +370,16 @@ void LIB_ARC::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
color = g_ItemSelectetColor;
}
else
{
color = aColor;
}
pos1 = TransformCoordinate( aTransformMatrix, m_ArcEnd ) + aOffset;
pos2 = TransformCoordinate( aTransformMatrix, m_ArcStart ) + aOffset;
posc = TransformCoordinate( aTransformMatrix, m_Pos ) + aOffset;
pos1 = aTransform.TransformCoordinate( m_ArcEnd ) + aOffset;
pos2 = aTransform.TransformCoordinate( m_ArcStart ) + aOffset;
posc = aTransform.TransformCoordinate( m_Pos ) + aOffset;
int pt1 = m_t1;
int pt2 = m_t2;
bool swap = MapAngles( &pt1, &pt2, aTransformMatrix );
bool swap = aTransform.MapAngles( &pt1, &pt2 );
if( swap )
{
EXCHG( pos1.x, pos2.x );
......@@ -335,18 +398,17 @@ void LIB_ARC::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
(m_Flags & IS_MOVED) ? color : ReturnLayerColor( LAYER_DEVICE_BACKGROUND ),
ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) );
else if( fill == FILLED_SHAPE && !aData )
GRFilledArc( &aPanel->m_ClipBox, aDC, posc.x, posc.y, pt1, pt2,
m_Radius, color, color );
GRFilledArc( &aPanel->m_ClipBox, aDC, posc.x, posc.y, pt1, pt2, m_Radius, color, color );
else
{
#ifdef DRAW_ARC_WITH_ANGLE
GRArc( &aPanel->m_ClipBox, aDC, posc.x, posc.y, pt1, pt2,
m_Radius, GetPenSize( ), color );
GRArc( &aPanel->m_ClipBox, aDC, posc.x, posc.y, pt1, pt2, m_Radius, GetPenSize(), color );
#else
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
}
......@@ -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()
{
int minX, minY, maxX, maxY, angleStart, angleEnd;
......@@ -377,13 +459,13 @@ start(%d, %d), end(%d, %d), radius %d" ),
return rect;
}
endPos = TransformCoordinate( DefaultTransformMatrix, m_ArcEnd );
startPos = TransformCoordinate( DefaultTransformMatrix, m_ArcStart );
centerPos = TransformCoordinate( DefaultTransformMatrix, m_Pos );
endPos = DefaultTransform.TransformCoordinate( m_ArcEnd );
startPos = DefaultTransform.TransformCoordinate( m_ArcStart );
centerPos = DefaultTransform.TransformCoordinate( m_Pos );
angleStart = m_t1;
angleEnd = m_t2;
if( MapAngles( &angleStart, &angleEnd, DefaultTransformMatrix ) )
if( DefaultTransform.MapAngles( &angleStart, &angleEnd ) )
{
EXCHG( endPos.x, startPos.x );
EXCHG( endPos.y, startPos.y );
......@@ -436,3 +518,259 @@ void LIB_ARC::DisplayInfo( WinEDA_DrawFrame* aFrame )
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 @@
#include "lib_draw_item.h"
class TRANSFORM;
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:
int m_Radius;
int m_t1; /* First radius angle of the arc in 0.1 degrees. */
......@@ -21,7 +76,7 @@ public:
int m_Width; /* Line width */
public:
LIB_ARC(LIB_COMPONENT * aParent);
LIB_ARC( LIB_COMPONENT * aParent );
LIB_ARC( const LIB_ARC& aArc );
~LIB_ARC() { }
virtual wxString GetClass() const
......@@ -51,14 +106,10 @@ public:
* @param aPosRef - a wxPoint to test
* @param aThreshold - max distance to this object (usually the half
* thickness of a line)
* @param aTransMat - the transform matrix
* @param aTransform - the transform matrix
* @return - True if the point aPosRef is near this object
*/
virtual bool HitTest( wxPoint aPosRef, int aThreshold, const int aTransMat[2][2] );
void Draw( WinEDA_DrawPanel * aPanel, wxDC * aDC, const wxPoint &aOffset,
int aColor, int aDrawMode, void* aData,
const int aTransformMatrix[2][2] );
virtual bool HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform );
virtual EDA_Rect GetBoundingBox();
virtual void DisplayInfo( WinEDA_DrawFrame* frame );
......@@ -68,6 +119,21 @@ public:
*/
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:
virtual LIB_DRAW_ITEM* DoGenCopy();
......@@ -87,7 +153,7 @@ protected:
virtual wxPoint DoGetPosition() { return m_Pos; }
virtual void DoMirrorHorizontal( const wxPoint& aCenter );
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 void DoSetWidth( int aWidth ) { m_Width = aWidth; }
};
......
......@@ -13,6 +13,7 @@
#include "general.h"
#include "protos.h"
#include "lib_bezier.h"
#include "transform.h"
LIB_BEZIER::LIB_BEZIER( LIB_COMPONENT* aParent ) :
......@@ -197,7 +198,7 @@ void LIB_BEZIER::DoMirrorHorizontal( const wxPoint& aCenter )
void LIB_BEZIER::DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
const int aTransform[2][2] )
const TRANSFORM& aTransform )
{
wxASSERT( aPlotter != NULL );
......@@ -211,7 +212,7 @@ void LIB_BEZIER::DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
for( i = 0; i < m_PolyPoints.size(); i++ )
{
wxPoint pos = m_PolyPoints[i];
pos = TransformCoordinate( aTransform, pos ) + aOffset;
pos = aTransform.TransformCoordinate( pos ) + aOffset;
Poly[i * 2] = pos.x;
Poly[i * 2 + 1] = pos.y;
}
......@@ -236,9 +237,8 @@ int LIB_BEZIER::GetPenSize()
return ( m_Width == 0 ) ? g_DrawDefaultLineThickness : m_Width;
}
void LIB_BEZIER::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
const wxPoint& aOffset, int aColor, int aDrawMode,
void* aData, const int aTransformMatrix[2][2] )
void LIB_BEZIER::drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOffset,
int aColor, int aDrawMode, void* aData, const TRANSFORM& aTransform )
{
wxPoint pos1;
std::vector<wxPoint> PolyPointsTraslated;
......@@ -253,8 +253,8 @@ void LIB_BEZIER::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
PolyPointsTraslated.clear();
for( unsigned int i = 0; i < m_PolyPoints.size() ; i++ )
PolyPointsTraslated.push_back( TransformCoordinate( aTransformMatrix,
m_PolyPoints[i] ) + aOffset );
PolyPointsTraslated.push_back( aTransform.TransformCoordinate( m_PolyPoints[i] ) +
aOffset );
if( aColor < 0 ) // Used normal color or selected color
{
......@@ -305,7 +305,7 @@ bool LIB_BEZIER::HitTest( const wxPoint& aRefPos )
// Have a minimal tolerance for hit test
if ( mindist < MINIMUM_SELECTION_DISTANCE )
mindist = MINIMUM_SELECTION_DISTANCE;
return HitTest( aRefPos, mindist, DefaultTransformMatrix );
return HitTest( aRefPos, mindist, DefaultTransform );
}
/** Function HitTest
......@@ -314,14 +314,14 @@ bool LIB_BEZIER::HitTest( const wxPoint& aRefPos )
* @param aThreshold = max distance to a segment
* @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;
for( unsigned ii = 1; ii < GetCornerCount(); ii++ )
{
start = TransformCoordinate( aTransMat, m_PolyPoints[ii - 1] );
end = TransformCoordinate( aTransMat, m_PolyPoints[ii] );
start = aTransform.TransformCoordinate( m_PolyPoints[ii - 1] );
end = aTransform.TransformCoordinate( m_PolyPoints[ii] );
if ( TestSegmentHit( aPosRef, start, end, aThreshold ) )
return true;
......
......@@ -11,6 +11,12 @@
/**************************************************/
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:
int m_Width; /* Line width */
std::vector<wxPoint> m_BezierPoints; // list of parameter (3|4)
......@@ -54,10 +60,10 @@ public:
/**
* @param aPosRef = a wxPoint to test
* @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
*/
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
......@@ -69,10 +75,6 @@ public:
*/
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 );
protected:
......@@ -93,7 +95,7 @@ protected:
virtual wxPoint DoGetPosition() { return m_PolyPoints[0]; }
virtual void DoMirrorHorizontal( const wxPoint& aCenter );
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 void DoSetWidth( int aWidth ) { m_Width = aWidth; }
};
......
......@@ -12,6 +12,7 @@
#include "general.h"
#include "protos.h"
#include "lib_circle.h"
#include "transform.h"
LIB_CIRCLE::LIB_CIRCLE( LIB_COMPONENT* aParent ) :
......@@ -79,7 +80,7 @@ bool LIB_CIRCLE::HitTest( const wxPoint& aPosRef )
if( 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 )
* thickness of a line)
* @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 ) +
( (double) relpos.y * relpos.y ) ) );
......@@ -169,9 +170,9 @@ void LIB_CIRCLE::DoMirrorHorizontal( const wxPoint& aCenter )
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 )
{
......@@ -193,9 +194,8 @@ int LIB_CIRCLE::GetPenSize()
}
void LIB_CIRCLE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
const wxPoint& aOffset, int aColor, int aDrawMode,
void* aData, const int aTransformMatrix[2][2] )
void LIB_CIRCLE::drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOffset,
int aColor, int aDrawMode, void* aData, const TRANSFORM& aTransform )
{
wxPoint pos1;
......@@ -209,7 +209,7 @@ void LIB_CIRCLE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
else
color = aColor;
pos1 = TransformCoordinate( aTransformMatrix, m_Pos ) + aOffset;
pos1 = aTransform.TransformCoordinate( m_Pos ) + aOffset;
GRSetDrawMode( aDC, aDrawMode );
FILL_T fill = aData ? NO_FILL : m_Fill;
......@@ -217,8 +217,7 @@ void LIB_CIRCLE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
fill = NO_FILL;
if( fill == FILLED_WITH_BG_BODYCOLOR )
GRFilledCircle( &aPanel->m_ClipBox, aDC, pos1.x, pos1.y,
m_Radius, GetPenSize( ),
GRFilledCircle( &aPanel->m_ClipBox, aDC, pos1.x, pos1.y, m_Radius, GetPenSize(),
(m_Flags & IS_MOVED) ? color : ReturnLayerColor( LAYER_DEVICE_BACKGROUND ),
ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) );
else if( fill == FILLED_SHAPE )
......@@ -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 rect;
......@@ -267,3 +280,69 @@ void LIB_CIRCLE::DisplayInfo( WinEDA_DrawFrame* aFrame )
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 @@
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:
int m_Radius;
wxPoint m_Pos; /* Position or centre (Arc and Circle) or start point (segments) */
int m_Width; /* Line width */
public:
LIB_CIRCLE(LIB_COMPONENT * aParent);
LIB_CIRCLE( LIB_COMPONENT * aParent );
LIB_CIRCLE( const LIB_CIRCLE& aCircle );
~LIB_CIRCLE() { }
virtual wxString GetClass() const
......@@ -47,23 +73,34 @@ public:
* @param aPosRef - a wxPoint to test
* @param aThreshold - max distance to this object (usually the half
* thickness of a line)
* @param aTransMat - the transform matrix
* @param aTransform - the transform matrix
* @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
*/
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 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:
virtual LIB_DRAW_ITEM* DoGenCopy();
......@@ -83,7 +120,7 @@ protected:
virtual wxPoint DoGetPosition() { return m_Pos; }
virtual void DoMirrorHorizontal( const wxPoint& aCenter );
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 void DoSetWidth( int aWidth ) { m_Width = aWidth; }
};
......
......@@ -4,17 +4,11 @@
#include "fctsys.h"
#include "gr_basic.h"
#include "common.h"
#include "class_drawpanel.h"
#include "plot_common.h"
#include "drawtxt.h"
#include "trigo.h"
#include "bezier_curves.h"
#include "confirm.h"
#include "wxstruct.h"
#include "program.h"
#include "general.h"
#include "protos.h"
#include "general.h"
#include "lib_draw_item.h"
const int fill_tab[3] = { 'N', 'F', 'f' };
......@@ -30,12 +24,13 @@ LIB_DRAW_ITEM::LIB_DRAW_ITEM( KICAD_T aType,
FILL_T aFillType ) :
EDA_BaseStruct( aType )
{
m_Unit = aUnit;
m_Convert = aConvert;
m_Fill = aFillType;
m_Parent = (EDA_BaseStruct*) aComponent;
m_typeName = _( "Undefined" );
m_isFillable = false;
m_Unit = aUnit;
m_Convert = aConvert;
m_Fill = aFillType;
m_Parent = (EDA_BaseStruct*) aComponent;
m_typeName = _( "Undefined" );
m_isFillable = false;
m_eraseLastDrawItem = false;
}
......@@ -111,3 +106,44 @@ bool LIB_DRAW_ITEM::operator<( const LIB_DRAW_ITEM& aOther ) const
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 @@
#define _LIB_DRAW_ITEM_H_
#include "base_struct.h"
#include "transform.h"
#include <boost/ptr_container/ptr_vector.hpp>
......@@ -20,6 +21,11 @@ class LIB_PIN;
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
......@@ -51,7 +57,53 @@ typedef std::vector< LIB_PIN* > LIB_PIN_LIST;
*/
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:
/**
......@@ -93,7 +145,7 @@ public:
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.
* It typically would be called on a left click when a draw tool is selected in
......@@ -103,30 +155,36 @@ public:
*
* @param aEditMode - The editing mode being performed. See base_struct.h for a list
* of mode flags.
* @param aStartPoint - The where the editing mode was started. This may or may not
* be required depending on the item being edited and the edit
* mode.
* @param aPosition - The position in drawing coordinates where the editing mode was
* started. This may or may not be required depending on the item
* 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
* called for each additional left click when the mouse is captured while the item
* 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.
*
* 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
* purposes
......@@ -140,11 +198,10 @@ public:
* to force no fill mode ( has meaning only for items what
* can be filled ). used in printing or moving objects mode
* 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,
const wxPoint &aOffset, int aColor, int aDrawMode,
void* aData, const int aTransformMatrix[2][2] ) = 0;
virtual void Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint &aOffset, int aColor,
int aDrawMode, void* aData, const TRANSFORM& aTransform );
/**
* @return the size of the "pen" that be used to draw or plot this item
......@@ -152,7 +209,7 @@ public:
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 aErrorMsg - Error message if write fails.
......@@ -183,10 +240,10 @@ public:
* @param aPosRef - a wxPoint to test
* @param aThreshold - max distance to this object (usually the half
* thickness of a line)
* @param aTransMat - the transform matrix
* @param aTransform - the transform matrix
* @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
......@@ -247,7 +304,7 @@ public:
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.
*
......@@ -270,6 +327,11 @@ public:
DoMirrorHorizontal( aCenter );
}
/**
* Rotate the draw item.
*/
virtual void Rotate() {}
/**
* Plot the draw item using the plot object.
*
......@@ -278,8 +340,7 @@ public:
* @param aFill - Flag to indicate whether or not the object is filled.
* @param aTransform - The plot transform.
*/
void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
const int aTransform[2][2] )
void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill, const TRANSFORM& aTransform )
{
DoPlot( aPlotter, aOffset, aFill, aTransform );
}
......@@ -315,6 +376,27 @@ public:
* @return - True if the draw item has been added to the parent component.
*/
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:
virtual LIB_DRAW_ITEM* DoGenCopy() = 0;
......@@ -337,7 +419,7 @@ protected:
virtual wxPoint DoGetPosition() = 0;
virtual void DoMirrorHorizontal( const wxPoint& aCenter ) = 0;
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 void DoSetWidth( int aWidth ) = 0;
......@@ -354,16 +436,42 @@ protected:
/*********************************************/
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:
LIB_TEXT(LIB_COMPONENT * aParent);
LIB_TEXT( LIB_COMPONENT * aParent );
LIB_TEXT( const LIB_TEXT& aText );
~LIB_TEXT() { }
virtual wxString GetClass() const
{
return wxT( "LIB_TEXT" );
}
/**
* Write text object out to a FILE in "*.lib" format.
*
......@@ -384,11 +492,10 @@ public:
/**
* @param aPosRef = a wxPoint to test, in eeschema coordinates
* @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
*/
virtual bool HitTest( wxPoint aPosRef, int aThreshold,
const int aTransMat[2][2] );
virtual bool HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform );
/**
* Test if the given rectangle intersects this object.
......@@ -408,14 +515,27 @@ public:
*/
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 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:
virtual LIB_DRAW_ITEM* DoGenCopy();
......@@ -437,7 +557,7 @@ protected:
virtual wxPoint DoGetPosition() { return m_Pos; }
virtual void DoMirrorHorizontal( const wxPoint& aCenter );
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 void DoSetWidth( int aWidth ) { m_Width = aWidth; }
};
......
......@@ -17,15 +17,16 @@
#include "general.h"
#include "protos.h"
#include "class_libentry.h"
#include "transform.h"
#include <wx/tokenzr.h>
#include <wx/stream.h>
#include <wx/txtstrm.h>
/***************************/
/* class LibraryFieldEntry */
/***************************/
/*******************/
/* class LIB_FIELD */
/*******************/
/**
* a Field is a string linked to a component.
......@@ -82,6 +83,8 @@ void LIB_FIELD::Init( int id )
m_FieldId = id;
m_Size.x = m_Size.y = DEFAULT_SIZE_TEXT;
m_typeName = _( "Field" );
m_Orient = TEXT_ORIENT_HORIZ;
m_rotate = false;
// fields in RAM must always have names, because we are trying to get
// less dependent on field ids and more dependent on names.
......@@ -288,9 +291,8 @@ int LIB_FIELD::GetPenSize()
* if aData not NULL, aData must point a wxString which is used instead of
* the m_Text
*/
void LIB_FIELD::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
const wxPoint& aOffset, int aColor, int aDrawMode,
void* aData, const int aTransformMatrix[2][2] )
void LIB_FIELD::drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOffset,
int aColor, int aDrawMode, void* aData, const TRANSFORM& aTransform )
{
wxPoint text_pos;
int color;
......@@ -312,29 +314,22 @@ void LIB_FIELD::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
}
if( color < 0 )
{
switch( m_FieldId )
{
case REFERENCE:
color = ReturnLayerColor( LAYER_REFERENCEPART );
break;
color = GetDefaultColor();
case VALUE:
color = ReturnLayerColor( LAYER_VALUEPART );
break;
text_pos = aTransform.TransformCoordinate( m_Pos ) + aOffset;
default:
color = ReturnLayerColor( LAYER_FIELDS );
break;
}
}
wxString text;
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 );
DrawGraphicText( aPanel, aDC, text_pos, (EDA_Colors) color, *text,
m_Orient, m_Size, m_HJustify, m_VJustify, linewidth,
m_Italic, m_Bold );
DrawGraphicText( aPanel, aDC, text_pos, (EDA_Colors) color, text, m_Orient, m_Size,
m_HJustify, m_VJustify, linewidth, m_Italic, m_Bold );
/* Set to one (1) to draw bounding box around field text to validate
* bounding box calculation. */
......@@ -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
* 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,
*/
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 )
* @param aThreshold = unused here (TextHitTest calculates its threshold )
* @param aTransMat = the transform matrix
*/
bool LIB_FIELD::HitTest( wxPoint aPosRef, int aThreshold,
const int aTransMat[2][2] )
bool LIB_FIELD::HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform )
{
int extraCharCount = 0;
// Reference designator text has one or 2 additional character (displays
......@@ -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;
m_Pos = physicalpos;
/* The text orientation may need to be flipped if the
* transformation matrix causes xy axes to be flipped.
* 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;
EXCHG( m_Orient, orient );
......@@ -501,7 +509,7 @@ void LIB_FIELD::DoMirrorHorizontal( const wxPoint& center )
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()
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 @@
*/
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:
int m_FieldId; ///< @see enum NumFieldType
......@@ -67,10 +93,6 @@ public:
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
* @return true is this field is visible, false if flagged invisible
......@@ -98,11 +120,10 @@ public:
* @param aPosRef = a wxPoint to test
* @param aThreshold = max distance to this object (usually the half
* thickness of a line)
* @param aTransMat = the transform matrix
* @param aTransform = the transform matrix
* @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 operator=( const LIB_FIELD& field )
{
......@@ -134,6 +155,25 @@ public:
*/
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:
virtual LIB_DRAW_ITEM* DoGenCopy();
......@@ -157,7 +197,7 @@ protected:
virtual wxPoint DoGetPosition( void ) { return m_Pos; }
virtual void DoMirrorHorizontal( const wxPoint& center );
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 void DoSetWidth( int width ) { m_Width = width; }
};
......
......@@ -13,6 +13,7 @@
#include "general.h"
#include "protos.h"
#include "lib_polyline.h"
#include "transform.h"
LIB_POLYLINE::LIB_POLYLINE( LIB_COMPONENT* aParent ) :
......@@ -186,7 +187,7 @@ void LIB_POLYLINE::DoMirrorHorizontal( const wxPoint& aCenter )
void LIB_POLYLINE::DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
const int aTransform[2][2] )
const TRANSFORM& aTransform )
{
wxASSERT( aPlotter != NULL );
......@@ -200,7 +201,7 @@ void LIB_POLYLINE::DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill
for( i = 0; i < m_PolyPoints.size(); i++ )
{
wxPoint pos = m_PolyPoints[i];
pos = TransformCoordinate( aTransform, pos ) + aOffset;
pos = aTransform.TransformCoordinate(pos ) + aOffset;
Poly[i * 2] = pos.x;
Poly[i * 2 + 1] = pos.y;
}
......@@ -232,9 +233,9 @@ int LIB_POLYLINE::GetPenSize()
}
void LIB_POLYLINE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
const wxPoint& aOffset, int aColor, int aDrawMode,
void* aData, const int aTransformMatrix[2][2] )
void LIB_POLYLINE::drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOffset,
int aColor, int aDrawMode, void* aData,
const TRANSFORM& aTransform )
{
wxPoint pos1;
int color = ReturnLayerColor( LAYER_DEVICE );
......@@ -273,8 +274,7 @@ void LIB_POLYLINE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ )
{
Buf_Poly_Drawings[ii] = TransformCoordinate( aTransformMatrix,
m_PolyPoints[ii] ) + aOffset;
Buf_Poly_Drawings[ii] = aTransform.TransformCoordinate( m_PolyPoints[ii] ) + aOffset;
}
FILL_T fill = aData ? NO_FILL : m_Fill;
......@@ -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
* tests if the given wxPoint is within the bounds of this object.
......@@ -319,7 +331,7 @@ bool LIB_POLYLINE::HitTest( const wxPoint& aRefPos )
// Have a minimal tolerance for hit test
if( 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 )
* @param aThreshold = max distance to a segment
* @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;
for( unsigned ii = 1; ii < GetCornerCount(); ii++ )
{
start = TransformCoordinate( aTransMat, m_PolyPoints[ii - 1] );
end = TransformCoordinate( aTransMat, m_PolyPoints[ii] );
start = aTransform.TransformCoordinate( m_PolyPoints[ii - 1] );
end = aTransform.TransformCoordinate( m_PolyPoints[ii] );
if( TestSegmentHit( aPosRef, start, end, aThreshold ) )
return true;
......@@ -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 )
{
wxString msg;
......@@ -380,8 +408,7 @@ void LIB_POLYLINE::DisplayInfo( WinEDA_DrawFrame* aFrame )
LIB_DRAW_ITEM::DisplayInfo( aFrame );
msg = ReturnStringFromValue( g_UserUnit, m_Width,
EESCHEMA_INTERNAL_UNIT, true );
msg = ReturnStringFromValue( g_UserUnit, m_Width, EESCHEMA_INTERNAL_UNIT, true );
aFrame->AppendMsgPanel(_( "Line width" ), msg, BLUE );
......@@ -390,3 +417,108 @@ void LIB_POLYLINE::DisplayInfo( WinEDA_DrawFrame* aFrame )
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 @@
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:
int m_Width; /* Line width */
std::vector<wxPoint> m_PolyPoints; // list of points (>= 2)
int m_ModifyIndex; // Index of the polyline point to modify
public:
LIB_POLYLINE(LIB_COMPONENT * aParent);
LIB_POLYLINE( LIB_COMPONENT * aParent );
LIB_POLYLINE( const LIB_POLYLINE& aPolyline );
~LIB_POLYLINE() { }
......@@ -38,6 +63,11 @@ public:
void AddPoint( const wxPoint& aPoint );
/**
* Delete the segment at \a aPosition.
*/
void DeleteSegment( const wxPoint aPosition );
/**
* @return the number of corners
*/
......@@ -54,11 +84,10 @@ public:
/**
* @param aPosRef = a wxPoint to test
* @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
*/
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
......@@ -70,12 +99,23 @@ public:
*/
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 );
/**
* 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:
virtual LIB_DRAW_ITEM* DoGenCopy();
......@@ -94,10 +134,10 @@ protected:
virtual wxPoint DoGetPosition() { return m_PolyPoints[0]; }
virtual void DoMirrorHorizontal( const wxPoint& aCenter );
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 void DoSetWidth( int aWidth ) { m_Width = aWidth; }
};
#endif // _LIB_POLYLIN_H_
#endif // _LIB_POLYLINE_H_
......@@ -12,6 +12,7 @@
#include "general.h"
#include "protos.h"
#include "lib_rectangle.h"
#include "transform.h"
LIB_RECTANGLE::LIB_RECTANGLE( LIB_COMPONENT* aParent ) :
......@@ -141,12 +142,12 @@ void LIB_RECTANGLE::DoMirrorHorizontal( const wxPoint& aCenter )
void LIB_RECTANGLE::DoPlot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
const int aTransform[2][2] )
const TRANSFORM& aTransform )
{
wxASSERT( aPlotter != NULL );
wxPoint pos = TransformCoordinate( aTransform, m_Pos ) + aOffset;
wxPoint end = TransformCoordinate( aTransform, m_End ) + aOffset;
wxPoint pos = aTransform.TransformCoordinate( m_Pos ) + aOffset;
wxPoint end = aTransform.TransformCoordinate( m_End ) + aOffset;
if( aFill && m_Fill == FILLED_WITH_BG_BODYCOLOR )
{
......@@ -167,9 +168,9 @@ int LIB_RECTANGLE::GetPenSize()
return ( m_Width == 0 ) ? g_DrawDefaultLineThickness : m_Width;
}
void LIB_RECTANGLE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
const wxPoint& aOffset, int aColor, int aDrawMode,
void* aData, const int aTransformMatrix[2][2] )
void LIB_RECTANGLE::drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC,
const wxPoint& aOffset, int aColor, int aDrawMode,
void* aData, const TRANSFORM& aTransform )
{
wxPoint pos1, pos2;
......@@ -183,8 +184,8 @@ void LIB_RECTANGLE::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
else
color = aColor;
pos1 = TransformCoordinate( aTransformMatrix, m_Pos ) + aOffset;
pos2 = TransformCoordinate( aTransformMatrix, m_End ) + aOffset;
pos1 = aTransform.TransformCoordinate( m_Pos ) + aOffset;
pos2 = aTransform.TransformCoordinate( m_End ) + aOffset;
FILL_T fill = aData ? NO_FILL : m_Fill;
if( aColor >= 0 )
......@@ -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 )
{
wxString msg;
......@@ -250,7 +265,7 @@ bool LIB_RECTANGLE::HitTest( const wxPoint& aRefPoint )
if( 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 )
* of a line)
* @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 actualEnd = TransformCoordinate( aTransMat, m_End );
wxPoint actualStart = aTransform.TransformCoordinate( m_Pos );
wxPoint actualEnd = aTransform.TransformCoordinate( m_End );
// locate lower segment
wxPoint start, end;
......@@ -296,3 +311,105 @@ bool LIB_RECTANGLE::HitTest( wxPoint aRefPoint, int aThreshold, const int aTrans
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 @@
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:
wxPoint m_End; /* Rectangle end point. */
wxPoint m_Pos; /* Rectangle start point. */
......@@ -20,7 +45,7 @@ public:
bool m_isStartPointSelected; /* Flag: is the upper left edge selected ? */
public:
LIB_RECTANGLE(LIB_COMPONENT * aParent);
LIB_RECTANGLE( LIB_COMPONENT * aParent );
LIB_RECTANGLE( const LIB_RECTANGLE& aRect );
~LIB_RECTANGLE() { }
virtual wxString GetClass() const
......@@ -50,23 +75,34 @@ public:
* @param aPosRef - a wxPoint to test
* @param aThreshold - max distance to this object (usually the half
* thickness of a line)
* @param aTransMat - the transform matrix
* @param aTransform - the transform matrix
* @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
*/
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 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:
virtual LIB_DRAW_ITEM* DoGenCopy();
......@@ -87,7 +123,7 @@ protected:
virtual wxPoint DoGetPosition() { return m_Pos; }
virtual void DoMirrorHorizontal( const wxPoint& aCenter );
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 void DoSetWidth( int aWidth ) { m_Width = aWidth; }
};
......
......@@ -19,6 +19,7 @@
#include "lib_draw_item.h"
#include "general.h"
#include "protos.h"
#include "transform.h"
LIB_TEXT::LIB_TEXT(LIB_COMPONENT * aParent) :
......@@ -27,6 +28,7 @@ LIB_TEXT::LIB_TEXT(LIB_COMPONENT * aParent) :
{
m_Size = wxSize( 50, 50 );
m_typeName = _( "Text" );
m_rotate = false;
}
......@@ -38,9 +40,8 @@ bool LIB_TEXT::Save( FILE* ExportFile )
// changed to '~'
text.Replace( wxT( " " ), wxT( "~" ) );
if( fprintf( ExportFile, "T %d %d %d %d %d %d %d %s ", m_Orient,
m_Pos.x, m_Pos.y, m_Size.x, m_Attributs, m_Unit, m_Convert,
CONV_TO_UTF8( text ) ) < 0 )
if( fprintf( ExportFile, "T %d %d %d %d %d %d %d %s ", m_Orient, m_Pos.x, m_Pos.y,
m_Size.x, m_Attributs, m_Unit, m_Convert, CONV_TO_UTF8( text ) ) < 0 )
return false;
if( fprintf( ExportFile, " %s %d", m_Italic ? "Italic" : "Normal",
( m_Bold > 0 ) ? 1 : 0 ) < 0 )
......@@ -82,8 +83,7 @@ bool LIB_TEXT::Load( char* line, wxString& errorMsg )
if( cnt < 8 )
{
errorMsg.Printf( _( "text only had %d parameters of the required 8" ),
cnt );
errorMsg.Printf( _( "text only had %d parameters of the required 8" ), cnt );
return false;
}
......@@ -141,7 +141,7 @@ bool LIB_TEXT::Load( char* line, wxString& errorMsg )
*/
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 )
* @param aThreshold = unused here (TextHitTest calculates its threshold )
* @param aTransMat = the transform matrix
*/
bool LIB_TEXT::HitTest( wxPoint aPosRef, int aThreshold,
const int aTransMat[2][2] )
bool LIB_TEXT::HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTransform )
{
wxPoint physicalpos = TransformCoordinate( aTransMat, m_Pos );
wxPoint physicalpos = aTransform.TransformCoordinate( m_Pos );
wxPoint tmp = m_Pos;
m_Pos = physicalpos;
/* The text orientation may need to be flipped if the
* transformation matrix causes xy axes to be flipped.
* 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;
EXCHG( m_Orient, orient );
bool hit = TextHitTest(aPosRef);
bool hit = TextHitTest( aPosRef );
EXCHG( m_Orient, orient );
m_Pos = tmp;
return hit;
......@@ -250,14 +250,14 @@ void LIB_TEXT::DoMirrorHorizontal( const wxPoint& center )
void LIB_TEXT::DoPlot( PLOTTER* plotter, const wxPoint& offset, bool fill,
const int transform[2][2] )
const TRANSFORM& aTransform )
{
wxASSERT( plotter != NULL );
/* The text orientation may need to be flipped if the
* transformation matrix causes xy axes to be flipped. */
int t1 = ( transform[0][0] != 0 ) ^ ( m_Orient != 0 );
wxPoint pos = TransformCoordinate( transform, m_Pos ) + offset;
int t1 = ( aTransform.x1 != 0 ) ^ ( m_Orient != 0 );
wxPoint pos = aTransform.TransformCoordinate( m_Pos ) + offset;
plotter->text( pos, UNSPECIFIED_COLOR, m_Text,
t1 ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT,
......@@ -285,13 +285,13 @@ int LIB_TEXT::GetPenSize( )
return pensize;
}
void LIB_TEXT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
const wxPoint& aOffset, int aColor, int aDrawMode,
void* aData, const int aTransformMatrix[2][2] )
void LIB_TEXT::drawGraphic( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOffset,
int aColor, int aDrawMode, void* aData, const TRANSFORM& aTransform )
{
wxPoint pos1, pos2;
int color = ReturnLayerColor( LAYER_DEVICE );
int color = GetDefaultColor();
if( aColor < 0 ) // Used normal color or selected color
{
......@@ -301,7 +301,7 @@ void LIB_TEXT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
else
color = aColor;
pos1 = TransformCoordinate( aTransformMatrix, m_Pos ) + aOffset;
pos1 = aTransform.TransformCoordinate( m_Pos ) + aOffset;
GRSetDrawMode( aDC, aDrawMode );
......@@ -309,7 +309,7 @@ void LIB_TEXT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
* orientation/mirror (needed when draw text in schematic)
*/
int orient = m_Orient;
if( aTransformMatrix[0][1] ) // Rotate component 90 degrees.
if( aTransform.y1 ) // Rotate component 90 degrees.
{
if( orient == TEXT_ORIENT_HORIZ )
orient = TEXT_ORIENT_VERT;
......@@ -329,27 +329,28 @@ void LIB_TEXT::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
* and use GetBoundaryBox to know the text coordinate considered as centered
*/
EDA_Rect bBox = GetBoundingBox();
pos1 = bBox.Centre(); // this is the coordinates of the graphic text relative to the component position
// in schematic Y axis orientation
pos1 = bBox.Centre(); // this is the coordinates of the graphic text relative to the
// component position in schematic Y axis orientation.
/* convert y coordinate from schematic to library Y axis orientation
* because we want to call TransformCoordinate to calculate real coordinates
*/
NEGATE( pos1.y );
pos1 = TransformCoordinate( aTransformMatrix, pos1 ) + aOffset;
DrawGraphicText( aPanel, aDC, pos1, (EDA_Colors) color, m_Text,
orient, m_Size, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
GetPenSize( ), m_Italic, m_Bold );
pos1 = aTransform.TransformCoordinate( pos1 ) + aOffset;
DrawGraphicText( aPanel, aDC, pos1, (EDA_Colors) color, m_Text, orient, m_Size,
GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, GetPenSize(),
m_Italic, m_Bold );
/* Enable this to draw the bounding box around the text field to validate
* the bounding box calculations.
*/
*/
#if 0
EDA_Rect grBox;
bBox.SetY( -bBox.GetY() );
bBox.SetHeight( -bBox.GetHeight());
grBox.SetOrigin( TransformCoordinate( aTransformMatrix, bBox.GetOrigin() ) );
grBox.SetEnd( TransformCoordinate( aTransformMatrix, bBox.GetEnd() ) );
grBox.SetOrigin( aTransform.TransformCoordinate( bBox.GetOrigin() ) );
grBox.SetEnd( aTransform.TransformCoordinate( bBox.GetEnd() ) );
grBox.Move( aOffset );
GRRect( &aPanel->m_ClipBox, aDC, grBox.GetOrigin().x, grBox.GetOrigin().y,
grBox.GetEnd().x, grBox.GetEnd().y, 0, LIGHTMAGENTA );
......@@ -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 )
{
wxString msg;
LIB_DRAW_ITEM::DisplayInfo( frame );
msg = ReturnStringFromValue( g_UserUnit, m_Width,
EESCHEMA_INTERNAL_UNIT, true );
msg = ReturnStringFromValue( g_UserUnit, m_Width, EESCHEMA_INTERNAL_UNIT, true );
frame->AppendMsgPanel( _( "Line width" ), msg, BLUE );
}
......@@ -394,3 +408,79 @@ EDA_Rect LIB_TEXT::GetBoundingBox()
rect.Normalize();
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 )
{
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() )
{
case COMPONENT_FIELD_DRAW_TYPE:
PlaceField( DC, (LIB_FIELD*) DrawEntry );
DrawEntry = NULL;
break;
case COMPONENT_PIN_DRAW_TYPE:
PlacePin( DC );
DrawEntry = NULL;
......@@ -53,16 +44,13 @@ void WinEDA_LibeditFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
}
else
{
DrawEntry =
m_component->LocateDrawItem( m_unit, m_convert, TYPE_NOT_INIT,
GetScreen()->m_MousePosition );
DrawEntry = m_component->LocateDrawItem( m_unit, m_convert, TYPE_NOT_INIT,
GetScreen()->m_MousePosition );
if( DrawEntry == NULL )
{
DrawEntry =
m_component->LocateDrawItem( m_unit, m_convert,
TYPE_NOT_INIT,
GetScreen()->m_Curseur );
DrawEntry = m_component->LocateDrawItem( m_unit, m_convert, TYPE_NOT_INIT,
GetScreen()->m_Curseur );
}
if( DrawEntry )
......@@ -106,35 +94,32 @@ void WinEDA_LibeditFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
if( m_drawItem->m_Flags & IS_NEW )
GraphicItemBeginDraw( DC );
else
{
SaveCopyInUndoList( m_component );
EndDrawGraphicItem( DC );
}
}
break;
case ID_LIBEDIT_DELETE_ITEM_BUTT:
DrawEntry =
m_component->LocateDrawItem( m_unit, m_convert, TYPE_NOT_INIT,
GetScreen()->m_MousePosition );
DrawEntry = m_component->LocateDrawItem( m_unit, m_convert, TYPE_NOT_INIT,
GetScreen()->m_MousePosition );
if( DrawEntry == NULL )
{
DrawEntry =
m_component->LocateDrawItem( m_unit, m_convert,
TYPE_NOT_INIT,
GetScreen()->m_Curseur );
DrawEntry = m_component->LocateDrawItem( m_unit, m_convert, TYPE_NOT_INIT,
GetScreen()->m_Curseur );
}
if( DrawEntry == NULL )
{
DisplayCmpDoc();
break;
}
SaveCopyInUndoList( m_component );
if( DrawEntry->Type() == COMPONENT_PIN_DRAW_TYPE )
DeletePin( DC, m_component, (LIB_PIN*) DrawEntry );
else
m_component->RemoveDrawItem( DrawEntry, DrawPanel, DC );
DrawEntry = NULL;
OnModify( );
break;
......@@ -145,10 +130,8 @@ void WinEDA_LibeditFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
SetToolID( 0, wxCURSOR_ARROW, wxEmptyString );
break;
default:
DisplayError( this,
wxT( "WinEDA_LibeditFrame::OnLeftClick error" ) );
DisplayError( this, wxT( "WinEDA_LibeditFrame::OnLeftClick error" ) );
SetToolID( 0, wxCURSOR_ARROW, wxEmptyString );
break;
}
......@@ -163,7 +146,7 @@ void WinEDA_LibeditFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
*/
void WinEDA_LibeditFrame::OnLeftDClick( wxDC* DC, const wxPoint& MousePos )
{
wxPoint pos = GetPosition();
wxPoint pos = GetPosition();
if( m_component == NULL )
return;
......@@ -175,9 +158,8 @@ void WinEDA_LibeditFrame::OnLeftDClick( wxDC* DC, const wxPoint& MousePos )
GetScreen()->m_MousePosition );
if( m_drawItem == NULL )
{
m_drawItem =
m_component->LocateDrawItem( m_unit, m_convert, TYPE_NOT_INIT,
GetScreen()->m_Curseur );
m_drawItem = m_component->LocateDrawItem( m_unit, m_convert, TYPE_NOT_INIT,
GetScreen()->m_Curseur );
}
if( m_drawItem == NULL )
{
......@@ -241,8 +223,7 @@ void WinEDA_LibeditFrame::OnLeftDClick( wxDC* DC, const wxPoint& MousePos )
default:
wxString msg;
msg.Printf( wxT( "WinEDA_LibeditFrame::OnLeftDClick Error: unknown \
StructType %d" ),
msg.Printf( wxT( "WinEDA_LibeditFrame::OnLeftDClick Error: unknown StructType %d" ),
m_drawItem->Type() );
DisplayError( this, msg );
break;
......
......@@ -11,6 +11,7 @@
#include "confirm.h"
#include "eda_doc.h"
#include "bitmaps.h"
#include "gr_basic.h"
#include "program.h"
#include "general.h"
......@@ -18,6 +19,7 @@
#include "eeschema_id.h"
#include "libeditframe.h"
#include "class_library.h"
#include "lib_polyline.h"
#include "kicad_device_context.h"
#include "hotkeys.h"
......@@ -163,6 +165,7 @@ WinEDA_LibeditFrame::WinEDA_LibeditFrame( WinEDA_SchematicFrame* aParent,
SetShowDeMorgan( false );
m_drawSpecificConvert = true;
m_drawSpecificUnit = false;
m_savedComponent = NULL;
m_HotkeysZoomAndGridList = s_Libedit_Hokeys_Descr;
// Give an icon
......@@ -743,13 +746,20 @@ void WinEDA_LibeditFrame::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_LIBEDIT_DELETE_CURRENT_POLY_SEGMENT:
{
// Delete the last created segment, while creating a polyline draw item
if( m_drawItem == NULL )
break;
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;
}
case ID_POPUP_LIBEDIT_DELETE_ITEM:
if( m_drawItem == NULL )
......@@ -780,8 +790,6 @@ void WinEDA_LibeditFrame::Process_Special_Functions( wxCommandEvent& event )
DrawPanel->MouseToCursorSchema();
if( m_drawItem->Type() == COMPONENT_PIN_DRAW_TYPE )
StartMovePin( &dc );
else if( m_drawItem->Type() == COMPONENT_FIELD_DRAW_TYPE )
StartMoveField( &dc, (LIB_FIELD*) m_drawItem );
else
StartMoveDrawSymbol( &dc );
break;
......@@ -798,35 +806,63 @@ void WinEDA_LibeditFrame::Process_Special_Functions( wxCommandEvent& event )
|| m_drawItem->Type() == COMPONENT_ARC_DRAW_TYPE
)
{
SaveCopyInUndoList( m_component );
StartModifyDrawSymbol( &dc );
}
break;
case ID_POPUP_LIBEDIT_ROTATE_GRAPHIC_TEXT:
if( m_drawItem == NULL )
if( m_drawItem == NULL && m_drawItem->Type() != COMPONENT_GRAPHIC_TEXT_DRAW_TYPE )
break;
DrawPanel->CursorOff( &dc );
DrawPanel->MouseToCursorSchema();
if( (m_drawItem->m_Flags & IS_NEW) == 0 )
if( !m_drawItem->InEditMode() )
{
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 );
break;
case ID_POPUP_LIBEDIT_FIELD_ROTATE_ITEM:
if( m_drawItem == NULL )
{
if( m_drawItem == NULL || ( m_drawItem->Type() != COMPONENT_FIELD_DRAW_TYPE ) )
break;
DrawPanel->CursorOff( &dc );
DrawPanel->MouseToCursorSchema();
if( m_drawItem->Type() == COMPONENT_FIELD_DRAW_TYPE )
if( !m_drawItem->InEditMode() )
{
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 );
break;
}
case ID_POPUP_LIBEDIT_FIELD_EDIT_ITEM:
if( m_drawItem == NULL )
......@@ -925,9 +961,20 @@ void WinEDA_LibeditFrame::EnsureActiveLibExists()
m_library = NULL;
}
void WinEDA_LibeditFrame::SetLanguage( wxCommandEvent& event )
{
WinEDA_BasicFrame::SetLanguage( event );
WinEDA_SchematicFrame *parent = (WinEDA_SchematicFrame *)GetParent();
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;
*/
class WinEDA_LibeditFrame : public WinEDA_DrawFrame
{
LIB_COMPONENT* m_savedComponent; ///< Temporary copy of current component during edit.
public:
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)
......@@ -94,11 +96,9 @@ public:
void OnLeftDClick( wxDC* DC, const wxPoint& MousePos );
SCH_SCREEN* GetScreen() { return (SCH_SCREEN*) GetBaseScreen(); }
void OnHotKey( wxDC* DC, int hotkey,
EDA_BaseStruct* DrawStruct );
void OnHotKey( wxDC* DC, int hotkey, EDA_BaseStruct* DrawStruct );
void GeneralControle( wxDC* DC,
wxPoint MousePositionInPixels );
void GeneralControle( wxDC* DC, wxPoint MousePositionInPixels );
void LoadSettings();
void SaveSettings();
......@@ -167,6 +167,8 @@ public:
FILL_T GetFillStyle( void ) { return m_drawFillStyle; }
void DeleteSavedComponent();
private:
/**
......@@ -182,16 +184,14 @@ private:
void SelectActiveLibrary();
void SaveActiveLibrary( wxCommandEvent& event );
bool LoadOneLibraryPartAux( CMP_LIB_ENTRY* LibEntry,
CMP_LIBRARY* Library );
bool LoadOneLibraryPartAux( CMP_LIB_ENTRY* LibEntry, CMP_LIBRARY* Library );
void DisplayCmpDoc();
void EditComponentProperties();
// General editing
public:
void SaveCopyInUndoList( EDA_BaseStruct* ItemToCopy,
int flag_type_command = 0 );
void SaveCopyInUndoList( EDA_BaseStruct* ItemToCopy, int flag_type_command = 0 );
private:
void GetComponentFromUndoList( wxCommandEvent& event );
......@@ -199,9 +199,7 @@ private:
// Editing pins
void CreatePin( wxDC* DC );
void DeletePin( wxDC* DC,
LIB_COMPONENT* LibEntry,
LIB_PIN* Pin );
void DeletePin( wxDC* DC, LIB_COMPONENT* LibEntry, LIB_PIN* Pin );
void StartMovePin( wxDC* DC );
// Editing anchor
......@@ -215,16 +213,10 @@ private:
void EndDrawGraphicItem( wxDC* DC );
void LoadOneSymbol();
void SaveOneSymbol();
void EditGraphicSymbol( wxDC* DC,
LIB_DRAW_ITEM* DrawItem );
void EditGraphicSymbol( 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();
void RotateField( wxDC* DC, LIB_FIELD* Field );
void PlaceField( wxDC* DC, LIB_FIELD* Field );
void EditField( wxDC* DC, LIB_FIELD* Field );
void StartMoveField( wxDC* DC, LIB_FIELD* field );
public:
/* Block commands: */
......@@ -311,9 +303,8 @@ protected:
* @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)
*/
virtual void PrintPage( wxDC* aDC, bool aPrint_Sheet_Ref,
int aPrintMask, bool aPrintMirrorMode,
void * aData = NULL);
virtual void PrintPage( wxDC* aDC, bool aPrint_Sheet_Ref, int aPrintMask,
bool aPrintMirrorMode, void * aData = NULL);
/** function SVG_Print_component
* Creates the SVG print file for the current edited component.
......
......@@ -15,120 +15,7 @@
#include "class_library.h"
static void ShowMoveField( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
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 )
{
......@@ -202,12 +89,11 @@ names in the alias list." ),
*/
if( m_library && m_library->FindEntry( Text ) != NULL )
{
msg.Printf( _(
"The field name <%s> conflicts with an existing \
msg.Printf( _( "The field name <%s> conflicts with an existing \
entry in the component library <%s>.\nPlease choose another name that does \
not conflict with any library entries." ),
GetChars( Text ),
GetChars( m_library->GetName() ) );
not conflict with any library entries." ),
GetChars( Text ),
GetChars( m_library->GetName() ) );
DisplayError( this, msg );
return;
}
......@@ -217,8 +103,8 @@ not conflict with any library entries."
Field->GetParent()->SetName( Text );
}
Field->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, g_XorMode, &fieldText,
DefaultTransformMatrix );
( ( LIB_DRAW_ITEM* )Field )->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, g_XorMode,
&fieldText, DefaultTransform );
if( !Text.IsEmpty() )
{
......@@ -237,57 +123,14 @@ not conflict with any library entries."
if( Field->m_Flags == 0 )
drawMode = GR_DEFAULT_DRAWMODE;
Field->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, drawMode, &fieldText,
DefaultTransformMatrix );
( ( LIB_DRAW_ITEM* )Field )->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, drawMode,
&fieldText, DefaultTransform );
OnModify();
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()
{
if( m_component == NULL )
......@@ -295,13 +138,11 @@ LIB_DRAW_ITEM* WinEDA_LibeditFrame::LocateItemUsingCursor()
if( ( m_drawItem == NULL ) || ( m_drawItem->m_Flags == 0 ) )
{
m_drawItem = m_component->LocateDrawItem( m_unit, m_convert,
TYPE_NOT_INIT,
m_drawItem = m_component->LocateDrawItem( m_unit, m_convert, TYPE_NOT_INIT,
GetScreen()->m_MousePosition );
if( m_drawItem == NULL )
m_drawItem = m_component->LocateDrawItem( m_unit, m_convert,
TYPE_NOT_INIT,
m_drawItem = m_component->LocateDrawItem( m_unit, m_convert, TYPE_NOT_INIT,
GetScreen()->m_Curseur );
}
......
......@@ -602,9 +602,8 @@ static void AddConnectedObjects( SCH_SHEET_PATH* sheetlist,
( pin->m_Convert != DrawLibItem->m_Convert ) )
continue;
wxPoint pos2 =
TransformCoordinate( DrawLibItem->m_Transform,
pin->m_Pos ) + DrawLibItem->m_Pos;
wxPoint pos2 = DrawLibItem->m_Transform.TransformCoordinate( pin->m_Pos ) +
DrawLibItem->m_Pos;
new_item = new NETLIST_OBJECT();
new_item->m_SheetListInclude = *sheetlist;
......
......@@ -275,7 +275,7 @@ another pin. Continue?" ) );
DrawPanel->CursorOff( DC );
bool showPinText = true;
CurrentPin->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, GR_DEFAULT_DRAWMODE,
&showPinText, DefaultTransformMatrix );
&showPinText, DefaultTransform );
DrawPanel->CursorOn( DC );
m_drawItem = NULL;
......@@ -346,14 +346,13 @@ static void DrawMovePin( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
{
CurrentPin->m_Pos = PinPreviousPos;
CurrentPin->Draw( panel, DC, wxPoint( 0, 0 ), -1, g_XorMode,
&showPinText, DefaultTransformMatrix );
&showPinText, DefaultTransform );
}
/* Redraw pin in new position */
CurrentPin->m_Pos.x = panel->GetScreen()->m_Curseur.x;
CurrentPin->m_Pos.y = -panel->GetScreen()->m_Curseur.y;
CurrentPin->Draw( panel, DC, wxPoint( 0, 0 ), -1, g_XorMode,
&showPinText, DefaultTransformMatrix );
CurrentPin->Draw( panel, DC, wxPoint( 0, 0 ), -1, g_XorMode, &showPinText, DefaultTransform );
PinPreviousPos = CurrentPin->m_Pos;
......@@ -471,14 +470,13 @@ void WinEDA_LibeditFrame::CreatePin( wxDC* DC )
DrawPanel->ForceCloseManageCurseur = AbortPinMove;
if( DC )
pin->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, wxCOPY, &showPinText,
DefaultTransformMatrix );
DefaultTransform );
}
}
static void CreateImagePins( LIB_PIN* Pin, int unit, int convert,
bool asDeMorgan )
static void CreateImagePins( LIB_PIN* Pin, int unit, int convert, bool asDeMorgan )
{
int ii;
LIB_PIN* NewPin;
......@@ -556,8 +554,7 @@ void WinEDA_LibeditFrame::GlobalSetPins( wxDC* DC, LIB_PIN* MasterPin, int id )
if( selected && ( Pin->m_Selected & IS_SELECTED ) == 0 )
continue;
Pin->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, g_XorMode,
&showPinText, DefaultTransformMatrix );
Pin->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, g_XorMode, &showPinText, DefaultTransform );
switch( id )
{
......@@ -574,8 +571,8 @@ void WinEDA_LibeditFrame::GlobalSetPins( wxDC* DC, LIB_PIN* MasterPin, int id )
break;
}
Pin->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, GR_DEFAULT_DRAWMODE,
&showPinText, DefaultTransformMatrix );
( ( LIB_DRAW_ITEM* )Pin )->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, GR_DEFAULT_DRAWMODE,
&showPinText, DefaultTransform );
}
}
......
......@@ -40,18 +40,18 @@ static void PlotNoConnectStruct( PLOTTER* plotter, SCH_NO_CONNECT* Struct )
static void PlotLibPart( PLOTTER* plotter, SCH_COMPONENT* DrawLibItem )
{
LIB_COMPONENT* Entry;
int TransMat[2][2];
TRANSFORM temp = TRANSFORM();
Entry = CMP_LIBRARY::FindLibraryComponent( DrawLibItem->m_ChipName );
if( Entry == NULL )
return;;
memcpy( TransMat, DrawLibItem->m_Transform, sizeof(TransMat) );
temp = DrawLibItem->m_Transform;
Entry->Plot( plotter, DrawLibItem->m_Multi, DrawLibItem->m_Convert,
DrawLibItem->m_Pos, TransMat );
Entry->Plot( plotter, DrawLibItem->m_Multi, DrawLibItem->m_Convert, DrawLibItem->m_Pos, temp );
bool isMulti = Entry->GetPartCount() > 1;
for( int fieldId = 0; fieldId < DrawLibItem->GetFieldCount(); fieldId++ )
{
PlotTextField( plotter, DrawLibItem, fieldId, isMulti, 0 );
......@@ -85,7 +85,7 @@ static void PlotTextField( PLOTTER* plotter, SCH_COMPONENT* DrawLibItem,
/* Calculate the text orientation, according to the component
* orientation/mirror */
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 )
orient = TEXT_ORIENT_VERT;
......
......@@ -5,14 +5,18 @@
#ifndef PROGRAM_H
#define PROGRAM_H
class TRANSFORM;
#define HIGHLIGHT_COLOR WHITE
#define TEXT_NO_VISIBLE 1
#include "wxEeschemaStruct.h"
#include "macros.h"
#include "base_struct.h"
#include "sch_item_struct.h"
#include "sch_item_struct.h"
#include "class_sch_component.h"
#include "class_sch_screen.h"
#include "class_drawsheet.h"
......@@ -26,10 +30,8 @@
* 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
* 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
......
......@@ -50,19 +50,6 @@ void IncrementLabelMember( wxString& name );
/****************/
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,
int OrigY,
int* ClosestX,
......
......@@ -809,14 +809,12 @@ int ReadPartDescr( wxWindow* frame, char* Line, FILE* f, wxString& aMsgDiag,
*aLineNum++;
if( ( fgets( Line, 256 - 1, f ) == NULL )
|| ( sscanf( Line, "%d %d %d %d",
&component->m_Transform[0][0],
&component->m_Transform[0][1],
&component->m_Transform[1][0],
&component->m_Transform[1][1] ) != 4 ) )
&component->m_Transform.x1,
&component->m_Transform.y1,
&component->m_Transform.x2,
&component->m_Transform.y2 ) != 4 ) )
{
aMsgDiag.Printf(
wxT( "Component orient error at line %d, aborted" ),
*aLineNum );
aMsgDiag.Printf( wxT( "Component orient error at line %d, aborted" ), *aLineNum );
Failed = TRUE;
return Failed;
}
......
......@@ -6,16 +6,11 @@
#include "fctsys.h"
#include "gr_basic.h"
#include "appl_wxstruct.h"
#include "common.h"
#include "class_drawpanel.h"
#include "confirm.h"
#include "eeschema_id.h"
#include "eeschema_id.h"
#include "program.h"
#include "general.h"
#include "trigo.h"
#include "protos.h"
#include "libeditframe.h"
#include "class_libentry.h"
#include "dialog_lib_edit_draw_item.h"
......@@ -24,38 +19,10 @@
#include "lib_polyline.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 {
START_POINT, END_POINT, OUTLINE
} SelectedPoint;
static void SymbolDisplayDraw( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
static void RedrawWhileMovingCursor( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
// 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
......@@ -65,7 +32,7 @@ void WinEDA_LibeditFrame::EditGraphicSymbol( wxDC* DC, LIB_DRAW_ITEM* DrawItem )
if( DrawItem == NULL )
return;
LIB_COMPONENT* component = DrawItem->GetParent();
LIB_COMPONENT* component = DrawItem->GetParent();
DIALOG_LIB_EDIT_DRAW_ITEM dialog( this, DrawItem->m_typeName );
......@@ -129,75 +96,29 @@ void WinEDA_LibeditFrame::EditGraphicSymbol( wxDC* DC, LIB_DRAW_ITEM* DrawItem )
static void AbortSymbolTraceOn( WinEDA_DrawPanel* Panel, wxDC* DC )
{
LIB_DRAW_ITEM* item;
WinEDA_LibeditFrame* parent = (WinEDA_LibeditFrame*) Panel->GetParent();
item = parent->GetDrawItem();
LIB_DRAW_ITEM* item = parent->GetDrawItem();
if( item == NULL )
return;
arcState.stateDrawArc = 0;
Panel->ManageCurseur = 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 );
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,
{
DrawPanel->ManageCurseur = SymbolDisplayDraw;
DrawPanel->ForceCloseManageCurseur = AbortSymbolTraceOn;
wxPoint drawPos = GetScreen()->GetCursorDrawPosition();
switch( m_ID_current_state )
{
case ID_LIBEDIT_BODY_ARC_BUTT:
{
LIB_ARC* Arc = new LIB_ARC( LibEntry );
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;
m_drawItem = new LIB_ARC( LibEntry );
break;
}
break;
case ID_LIBEDIT_BODY_CIRCLE_BUTT:
{
LIB_CIRCLE* Circle = new LIB_CIRCLE( LibEntry );
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;
m_drawItem = new LIB_CIRCLE( LibEntry );
break;
case ID_LIBEDIT_BODY_RECT_BUTT:
{
LIB_RECTANGLE* Square = new LIB_RECTANGLE( LibEntry );
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;
m_drawItem = new LIB_RECTANGLE( LibEntry );
break;
case ID_LIBEDIT_BODY_LINE_BUTT:
{
LIB_POLYLINE* polyline = new LIB_POLYLINE( LibEntry );
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;
m_drawItem = new LIB_POLYLINE( LibEntry );
break;
case ID_LIBEDIT_BODY_TEXT_BUTT:
{
LIB_TEXT* Text = new LIB_TEXT( LibEntry );
m_drawItem = Text;
Text->m_Size.x = Text->m_Size.y = m_textSize;
Text->m_Orient = m_textOrientation;
Text->m_Pos = GetScreen()->m_Curseur;
NEGATE( Text->m_Pos.y );
// Enter the graphic text info
DrawPanel->m_IgnoreMouseEvents = true;
......@@ -279,18 +163,13 @@ LIB_DRAW_ITEM* WinEDA_LibeditFrame::CreateGraphicItem( LIB_COMPONENT* LibEntry,
{
SAFE_DELETE( Text );
m_drawItem = NULL;
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
}
else
{
StartMoveDrawSymbol( DC );
Text->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, g_XorMode, NULL,
DefaultTransformMatrix );
m_drawItem = Text;
}
break;
}
break;
default:
DisplayError( this, wxT( "WinEDA_LibeditFrame::CreateGraphicItem() error" ) );
return NULL;
......@@ -298,11 +177,22 @@ LIB_DRAW_ITEM* WinEDA_LibeditFrame::CreateGraphicItem( LIB_COMPONENT* LibEntry,
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 )
m_drawItem->m_Unit = m_unit;
if( m_drawSpecificConvert )
m_drawItem->m_Convert = m_convert;
m_savedComponent = new LIB_COMPONENT( *m_component );
}
else
{
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
return NULL;
}
DrawPanel->MouseToCursorSchema();
......@@ -319,43 +209,15 @@ void WinEDA_LibeditFrame::GraphicItemBeginDraw( wxDC* DC )
if( m_drawItem == NULL )
return;
switch( m_drawItem->Type() )
{
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;
wxPoint pos = GetScreen()->GetCursorDrawPosition();
case COMPONENT_POLYLINE_DRAW_TYPE:
if( m_drawItem->ContinueEdit( pos ) )
{
wxPoint pos = GetScreen()->m_Curseur;
NEGATE( pos.y );
( (LIB_POLYLINE*) m_drawItem )->AddPoint( pos );
m_drawItem->Draw( DrawPanel, DC, pos, -1, g_XorMode, NULL, DefaultTransform );
return;
}
break;
case COMPONENT_LINE_DRAW_TYPE:
break;
default:
;
}
EndDrawGraphicItem( DC );
}
......@@ -372,19 +234,9 @@ static void RedrawWhileMovingCursor( WinEDA_DrawPanel* panel, wxDC* DC, bool era
return;
BASE_SCREEN* Screen = panel->GetScreen();
wxPoint pos;
/* Erase shape in the old position*/
if( erase )
{
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;
item->Draw( panel, DC, Screen->GetCursorDrawPosition(), -1, g_XorMode, NULL,
DefaultTransform );
}
......@@ -395,13 +247,14 @@ void WinEDA_LibeditFrame::StartMoveDrawSymbol( wxDC* DC )
SetCursor( wxCURSOR_HAND );
m_drawItem->m_Flags |= IS_MOVED;
StartCursor = GetScreen()->m_Curseur;
InitPosition = m_drawItem->GetPosition();
ItemPreviousPos = GetScreen()->m_Curseur;
if( m_drawItem->m_Unit != m_unit )
m_drawItem->m_Unit = m_unit;
m_savedComponent = new LIB_COMPONENT( *m_component );
m_drawItem->BeginEdit( IS_MOVED, GetScreen()->GetCursorDrawPosition() );
DrawPanel->ManageCurseur = RedrawWhileMovingCursor;
DrawPanel->ForceCloseManageCurseur = AbortSymbolTraceOn;
DrawPanel->ManageCurseur( DrawPanel, DC, TRUE );
DrawPanel->ManageCurseur( DrawPanel, DC, true );
}
......@@ -411,400 +264,25 @@ 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;
}
m_savedComponent = new LIB_COMPONENT( *m_component );
m_drawItem->BeginEdit( IS_RESIZED, GetScreen()->GetCursorDrawPosition() );
DrawPanel->ManageCurseur = SymbolDisplayDraw;
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.
static void SymbolDisplayDraw( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
{
int dx, dy;
int DrawMode = g_XorMode;
BASE_SCREEN* Screen = panel->GetScreen();
wxPoint currentCursorPosition = Screen->m_Curseur;
FILL_T fillStyle = NO_FILL;
LIB_DRAW_ITEM* item;
item = ( (WinEDA_LibeditFrame*) panel->GetParent() )->GetDrawItem();
LIB_DRAW_ITEM* item = ( (WinEDA_LibeditFrame*) panel->GetParent() )->GetDrawItem();
if( item == NULL )
return;
fillStyle = ( (WinEDA_LibeditFrame*) panel->GetParent() )->GetFillStyle();
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 );
}
}
item->Draw( panel, DC, Screen->GetCursorDrawPosition(), -1, g_XorMode, NULL,
DefaultTransform );
}
......@@ -816,282 +294,24 @@ void WinEDA_LibeditFrame::EndDrawGraphicItem( wxDC* DC )
if( m_component == NULL || m_drawItem == NULL )
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 )
SetCursor( wxCURSOR_PENCIL );
else
SetCursor( wxCURSOR_ARROW );
if( m_drawItem->m_Flags & IS_MOVED )
{
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 );
}
SaveCopyInUndoList( m_savedComponent );
DeleteSavedComponent();
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;
OnModify( );
OnModify();
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
}
//! @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 );
DrawPanel->Refresh();
}
#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:
m_Status = new_status;
}
void SetFlags( int aFlags ) { m_Flags = aFlags; }
int GetFlags() { return m_Flags; }
/**
* Function DisplayInfo
......
......@@ -167,6 +167,16 @@ public:
*/
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 */
/** function ClearUndoORRedoList (virtual).
......@@ -180,10 +190,7 @@ public:
* old commands this will empty the list of commands.
* Commands are deleted from the older to the last.
*/
virtual void ClearUndoORRedoList(
UNDO_REDO_CONTAINER& aList,
int
aItemCount = -1 ) = 0;
virtual void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ) = 0;
/** Function ClearUndoRedoList
* clear undo and redo list, using ClearUndoORRedoList()
......
......@@ -5,6 +5,9 @@
#ifndef MACROS_H
#define MACROS_H
#include <wx/wx.h>
#if wxUSE_UNICODE
#define CONV_TO_UTF8( wxstring ) ( (const char*) wxConvCurrent->cWX2MB( wxstring ) )
#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