Added documentation. Moved some functions from .h to .cpp files.

This commit is contained in:
Maciej Suminski 2014-03-07 10:26:33 +01:00
parent 88a0311afe
commit 3927c667cc
4 changed files with 321 additions and 113 deletions

View File

@ -29,6 +29,17 @@
#include <class_drawsegment.h>
bool EDIT_POINT::WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const
{
// Corners of the square
VECTOR2I topLeft = GetPosition() - aSize;
VECTOR2I bottomRight = GetPosition() + aSize;
return ( aPoint.x > topLeft.x && aPoint.y > topLeft.y &&
aPoint.x < bottomRight.x && aPoint.y < bottomRight.y );
}
EDIT_POINTS::EDIT_POINTS( EDA_ITEM* aParent ) :
EDA_ITEM( NOT_USED ), m_parent( aParent )
{
@ -61,6 +72,62 @@ EDIT_POINT* EDIT_POINTS::FindPoint( const VECTOR2I& aLocation )
}
EDIT_POINT* EDIT_POINTS::Previous( const EDIT_POINT& aPoint )
{
for( unsigned int i = 0; i < m_points.size(); ++i )
{
if( m_points[i] == aPoint )
{
if( i == 0 )
return &m_points[m_points.size() - 1];
else
return &m_points[i - 1];
}
}
for( unsigned int i = 0; i < m_lines.size(); ++i )
{
if( m_lines[i] == aPoint )
{
if( i == 0 )
return &m_lines[m_lines.size() - 1];
else
return &m_lines[i - 1];
}
}
return NULL;
}
EDIT_POINT* EDIT_POINTS::Next( const EDIT_POINT& aPoint )
{
for( unsigned int i = 0; i < m_points.size(); ++i )
{
if( m_points[i] == aPoint )
{
if( i == m_points.size() - 1 )
return &m_points[0];
else
return &m_points[i + 1];
}
}
for( unsigned int i = 0; i < m_lines.size(); ++i )
{
if( m_lines[i] == aPoint )
{
if( i == m_lines.size() - 1 )
return &m_lines[0];
else
return &m_lines[i + 1];
}
}
return NULL;
}
void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const
{
aGal->SetFillColor( KIGFX::COLOR4D( 1.0, 1.0, 1.0, 1.0 ) );
@ -79,3 +146,32 @@ void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const
aGal->PopDepth();
}
void EPC_45DEGREE::Apply()
{
// Current line vector
VECTOR2I lineVector( m_constrained.GetPosition() - m_constrainer.GetPosition() );
double angle = lineVector.Angle();
// Find the closest angle, which is a multiple of 45 degrees
double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0;
VECTOR2I newLineVector = lineVector.Rotate( newAngle - angle );
m_constrained.SetPosition( m_constrainer.GetPosition() + newLineVector );
}
void EPC_CIRCLE::Apply()
{
VECTOR2I centerToEnd = m_end.GetPosition() - m_center.GetPosition();
VECTOR2I centerToPoint = m_constrained.GetPosition() - m_center.GetPosition();
int radius = centerToEnd.EuclideanNorm();
double angle = centerToPoint.Angle();
VECTOR2I newLine( radius, 0 );
newLine = newLine.Rotate( angle );
m_constrained.SetPosition( m_center.GetPosition() + newLine );
}

View File

@ -34,23 +34,50 @@
class EDIT_POINT;
/**
* Class EDIT_POINT_CONSTRAINT
*
* Allows to describe constraints between two points. After the constrained point is changed,
* Apply() has to be called to fix its coordinates according to the implemented constraint.
*/
class EDIT_POINT_CONSTRAINT
{
public:
/**
* Constructor
*
* @param aConstrained is EDIT_POINT to which the constraint is applied.
*/
EDIT_POINT_CONSTRAINT( EDIT_POINT& aConstrained ) : m_constrained( aConstrained ) {};
virtual ~EDIT_POINT_CONSTRAINT() {};
/**
* Function Apply()
*
* Corrects coordinates of the constrained point.
*/
virtual void Apply() = 0;
protected:
EDIT_POINT& m_constrained;
EDIT_POINT& m_constrained; ///< Point that is constrained by rules implemented by Apply()
};
// TODO docs
/**
* Class EDIT_POINT
*
* Represents a single point that can be used for modifying items. It is directly related to one
* of points in a graphical item (e.g. vertex of a zone or center of a circle).
*/
class EDIT_POINT
{
public:
/**
* Constructor
*
* @param aPoint stores coordinates for EDIT_POINT.
*/
EDIT_POINT( const VECTOR2I& aPoint ) :
m_position( aPoint ), m_constraint( NULL ) {};
@ -59,25 +86,44 @@ public:
delete m_constraint;
}
/**
* Function GetPosition()
*
* Returns coordinates of an EDIT_POINT. Note that it may be different than coordinates of
* a graphical item that is bound to the EDIT_POINT.
*/
virtual VECTOR2I GetPosition() const
{
return m_position;
}
/**
* Function SetPosition()
*
* Sets new coordinates for an EDIT_POINT. It does not change the coordinates of a graphical
* item.
* @param aPosition are new coordinates.
*/
virtual void SetPosition( const VECTOR2I& aPosition )
{
m_position = aPosition;
}
bool WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const
{
VECTOR2I topLeft = GetPosition() - aSize;
VECTOR2I bottomRight = GetPosition() + aSize;
return ( aPoint.x > topLeft.x && aPoint.y > topLeft.y &&
aPoint.x < bottomRight.x && aPoint.y < bottomRight.y );
}
/**
* Function WithinPoint()
*
* Checks if given point is within a square centered in the EDIT_POINT position.
* @param aPoint is point to be checked.
* @param aSize is length of the square side.
*/
bool WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const;
/**
* Function SetConstraint()
*
* Sets a constraint for and EDIT_POINT.
* @param aConstraint is the constraint to be set.
*/
void SetConstraint( EDIT_POINT_CONSTRAINT* aConstraint )
{
if( m_constraint )
@ -86,22 +132,33 @@ public:
m_constraint = aConstraint;
}
/**
* Function ClearConstraint()
*
* Removes previously set constraint.
*/
void ClearConstraint()
{
delete m_constraint;
m_constraint = NULL;
}
EDIT_POINT_CONSTRAINT* GetConstraint() const
{
return m_constraint;
}
/**
* Function IsConstrained()
*
* Checks if point is constrained.
* @return True is point is constrained, false otherwise.
*/
bool IsConstrained() const
{
return m_constraint != NULL;
}
/**
* Function ApplyConstraint()
*
* Corrects coordinates of an EDIT_POINT by applying previously set constraint.
*/
void ApplyConstraint()
{
if( m_constraint )
@ -117,25 +174,40 @@ public:
static const int POINT_SIZE = 10;
protected:
VECTOR2I m_position;
EDIT_POINT_CONSTRAINT* m_constraint;
VECTOR2I m_position; ///< Position of EDIT_POINT
EDIT_POINT_CONSTRAINT* m_constraint; ///< Constraint for the point, NULL if none
};
/**
* Class EDIT_LINE
*
* Represents a line connecting two EDIT_POINTs. That allows to move them both by dragging the
* EDIT_POINT in the middle. As it uses references to EDIT_POINTs, all coordinates are
* automatically synchronized.
*/
class EDIT_LINE : public EDIT_POINT
{
public:
/**
* Constructor
*
* @param aOrigin is the origin of EDIT_LINE.
* @param aEnd is the end of EDIT_LINE.
*/
EDIT_LINE( EDIT_POINT& aOrigin, EDIT_POINT& aEnd ) :
EDIT_POINT( aOrigin.GetPosition() + ( aEnd.GetPosition() - aOrigin.GetPosition() ) / 2 ),
m_origin( aOrigin ), m_end( aEnd )
{
}
///> @copydoc EDIT_POINT::GetPosition()
virtual VECTOR2I GetPosition() const
{
return m_origin.GetPosition() + ( m_end.GetPosition() - m_origin.GetPosition() ) / 2;
}
///> @copydoc EDIT_POINT::GetPosition()
virtual void SetPosition( const VECTOR2I& aPosition )
{
VECTOR2I difference = aPosition - GetPosition();
@ -155,101 +227,110 @@ public:
}
private:
EDIT_POINT& m_origin;
EDIT_POINT& m_end;
EDIT_POINT& m_origin; ///< Origin point for a line
EDIT_POINT& m_end; ///< End point for a line
};
/**
* Class EDIT_POINTS
*
* EDIT_POINTS is a VIEW_ITEM that manages EDIT_POINTs and EDIT_LINEs and draws them.
*/
class EDIT_POINTS : public EDA_ITEM
{
public:
/**
* Constructor.
*
* @param aParent is the item to which EDIT_POINTs are related.
*/
EDIT_POINTS( EDA_ITEM* aParent );
/**
* Function FindPoint
* Function FindPoint()
*
* Returns a point that is at given coordinates or NULL if there is no such point.
* @param aLocation is the location for searched point.
*/
EDIT_POINT* FindPoint( const VECTOR2I& aLocation );
/**
* Function GetParent()
*
* Returns parent of the EDIT_POINTS.
*/
EDA_ITEM* GetParent() const
{
return m_parent;
}
/**
* Function AddPoint()
*
* Adds an EDIT_POINT.
* @param aPoint is the new point.
*/
void AddPoint( const EDIT_POINT& aPoint )
{
m_points.push_back( aPoint );
}
/**
* Function AddPoint()
*
* Adds an EDIT_POINT.
* @param aPoint are coordinates of the new point.
*/
void AddPoint( const VECTOR2I& aPoint )
{
AddPoint( EDIT_POINT( aPoint ) );
}
/**
* Function AddLine()
*
* Adds an EDIT_LINE.
* @param aLine is the new line.
*/
void AddLine( const EDIT_LINE& aLine )
{
m_lines.push_back( aLine );
}
/**
* Function AddLine()
*
* Adds an EDIT_LINE.
* @param aOrigin is the origin for a new line.
* @param aEnd is the end for a new line.
*/
void AddLine( EDIT_POINT& aOrigin, EDIT_POINT& aEnd )
{
m_lines.push_back( EDIT_LINE( aOrigin, aEnd ) );
}
EDIT_POINT* Previous( const EDIT_POINT& aPoint )
{
for( unsigned int i = 0; i < m_points.size(); ++i )
{
if( m_points[i] == aPoint )
{
if( i == 0 )
return &m_points[m_points.size() - 1];
else
return &m_points[i - 1];
}
}
/**
* Function Previous()
*
* Returns the point that is after the given point in the list.
* @param aPoint is the point that is supposed to be preceding the searched point.
* @return The point following aPoint in the list. If aPoint is the first in
* the list, the last from the list will be returned. If there are no points at all, NULL
* is returned.
*/
EDIT_POINT* Previous( const EDIT_POINT& aPoint );
for( unsigned int i = 0; i < m_lines.size(); ++i )
{
if( m_lines[i] == aPoint )
{
if( i == 0 )
return &m_lines[m_lines.size() - 1];
else
return &m_lines[i - 1];
}
}
return NULL;
}
EDIT_POINT* Next( const EDIT_POINT& aPoint )
{
for( unsigned int i = 0; i < m_points.size(); ++i )
{
if( m_points[i] == aPoint )
{
if( i == m_points.size() - 1 )
return &m_points[0];
else
return &m_points[i + 1];
}
}
for( unsigned int i = 0; i < m_lines.size(); ++i )
{
if( m_lines[i] == aPoint )
{
if( i == m_lines.size() - 1 )
return &m_lines[0];
else
return &m_lines[i + 1];
}
}
return NULL;
}
/**
* Function Next()
*
* Returns the point that is before the given point in the list.
* @param aPoint is the point that is supposed to be following the searched point.
* @return The point preceding aPoint in the list. If aPoint is the last in
* the list, the first point from the list will be returned. If there are no points at all,
* NULL is returned.
*/
EDIT_POINT* Next( const EDIT_POINT& aPoint );
EDIT_POINT& operator[]( unsigned int aIndex )
{
@ -261,18 +342,26 @@ public:
return m_points[aIndex];
}
/**
* Function Size()
*
* Returns number of stored points.
*/
unsigned int Size() const
{
return m_points.size();
}
///> @copydoc VIEW_ITEM::ViewBBox()
virtual const BOX2I ViewBBox() const
{
return m_parent->ViewBBox();
}
///> @copydoc VIEW_ITEM::ViewDraw()
virtual void ViewDraw( int aLayer, KIGFX::GAL* aGal ) const;
///> @copydoc VIEW_ITEM::ViewGetLayers()
virtual void ViewGetLayers( int aLayers[], int& aCount ) const
{
aCount = 1;
@ -284,19 +373,31 @@ public:
}
private:
EDA_ITEM* m_parent;
std::deque<EDIT_POINT> m_points;
std::deque<EDIT_LINE> m_lines;
EDA_ITEM* m_parent; ///< Parent of the EDIT_POINTs
std::deque<EDIT_POINT> m_points; ///< EDIT_POINTs for modifying m_parent
std::deque<EDIT_LINE> m_lines; ///< EDIT_LINEs for modifying m_parent
};
/**
* Class EPC_VERTICAL.
*
* EDIT_POINT_CONSTRAINT that imposes a constraint that two points have to have the same X coordinate.
*/
class EPC_VERTICAL : public EDIT_POINT_CONSTRAINT
{
public:
EPC_VERTICAL( EDIT_POINT& aConstrained, EDIT_POINT& aConstrainer ) :
/**
* Constructor.
*
* @param aConstrained is the point that is put under constrain.
* @param aConstrainer is the point that is the source of the constrain.
*/
EPC_VERTICAL( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) :
EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer )
{}
///> @copydoc EDIT_POINT_CONSTRAINT::Apply()
virtual void Apply()
{
VECTOR2I point = m_constrained.GetPosition();
@ -304,23 +405,30 @@ public:
m_constrained.SetPosition( point );
}
virtual std::list<EDIT_POINT*> GetConstrainers() const
{
return std::list<EDIT_POINT*>( 1, &m_constrainer );
}
private:
EDIT_POINT& m_constrainer;
const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint.
};
/**
* Class EPC_HORIZONTAL.
*
* EDIT_POINT_CONSTRAINT that imposes a constraint that two points have to have the same Y coordinate.
*/
class EPC_HORIZONTAL : public EDIT_POINT_CONSTRAINT
{
public:
/**
* Constructor.
*
* @param aConstrained is the point that is put under constrain.
* @param aConstrainer is the point that is the source of the constrain.
*/
EPC_HORIZONTAL( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) :
EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer )
{}
///> @copydoc EDIT_POINT_CONSTRAINT::Apply()
virtual void Apply()
{
VECTOR2I point = m_constrained.GetPosition();
@ -329,60 +437,64 @@ public:
}
private:
const EDIT_POINT& m_constrainer;
const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint.
};
/**
* Class EPC_45DEGREE
*
* EDIT_POINT_CONSTRAINT that imposes a constraint that two to be located at angle of 45 degree
* multiplicity.
*/
class EPC_45DEGREE : public EDIT_POINT_CONSTRAINT
{
public:
/**
* Constructor.
*
* @param aConstrained is the point that is put under constrain.
* @param aConstrainer is the point that is the source of the constrain.
*/
EPC_45DEGREE ( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) :
EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer )
{}
virtual void Apply()
{
// Current line vector
VECTOR2I lineVector( m_constrained.GetPosition() - m_constrainer.GetPosition() );
double angle = lineVector.Angle();
// Find the closest angle, which is a multiple of 45 degrees
double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0;
VECTOR2I newLineVector = lineVector.Rotate( newAngle - angle );
m_constrained.SetPosition( m_constrainer.GetPosition() + newLineVector );
}
///> @copydoc EDIT_POINT_CONSTRAINT::Apply()
virtual void Apply();
private:
const EDIT_POINT& m_constrainer;
const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint.
};
/**
* Class EPC_CIRCLE.
*
* EDIT_POINT_CONSTRAINT that imposes a constraint that a point has to lie on a circle.
*/
class EPC_CIRCLE : public EDIT_POINT_CONSTRAINT
{
public:
/**
* Constructor.
*
* @param aConstrained is the point that is put under constrain.
* @parama aCenter is the point that is the center of the circle.
* @parama aEnd is the point that decides on the radius of the circle.
*/
EPC_CIRCLE( EDIT_POINT& aConstrained, const EDIT_POINT& aCenter, const EDIT_POINT& aEnd ) :
EDIT_POINT_CONSTRAINT( aConstrained ), m_center( aCenter ), m_end( aEnd )
{}
virtual ~EPC_CIRCLE() {};
virtual void Apply()
{
VECTOR2I centerToEnd = m_end.GetPosition() - m_center.GetPosition();
VECTOR2I centerToPoint = m_constrained.GetPosition() - m_center.GetPosition();
int radius = centerToEnd.EuclideanNorm();
double angle = centerToPoint.Angle();
VECTOR2I newLine( radius, 0 );
newLine = newLine.Rotate( angle );
m_constrained.SetPosition( m_center.GetPosition() + newLine );
}
///> @copydoc EDIT_POINT_CONSTRAINT::Apply()
virtual void Apply();
private:
///> Point that imposes the constraint (center of the circle).
const EDIT_POINT& m_center;
///> Point that imposes the constraint (decides on the radius of the circle).
const EDIT_POINT& m_end;
};

View File

@ -159,6 +159,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent )
KIGFX::VIEW* view = getView();
PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
EDA_ITEM* item = selection.items.GetPickedItem( 0 );
EDIT_POINT constrainer( VECTOR2I( 0, 0 ) );
m_editPoints = EDIT_POINTS_FACTORY::Make( item );
if( !m_editPoints )
@ -220,7 +221,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent )
if( !m_dragPoint->IsConstrained() )
{
// Find a proper constraining point for 45 degrees mode
EDIT_POINT constrainer = get45DegConstrainer();
constrainer = get45DegConstrainer();
m_dragPoint->SetConstraint( new EPC_45DEGREE( *m_dragPoint, constrainer ) );
}
}

View File

@ -37,7 +37,6 @@ class SELECTION_TOOL;
*
* Tool that displays edit points allowing to modify items by dragging the points.
*/
class POINT_EDITOR : public TOOL_INTERACTIVE
{
public: