Loading pcbnew/tools/edit_points.cpp +96 −0 Original line number Diff line number Diff line Loading @@ -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 ) { Loading Loading @@ -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 ) ); Loading @@ -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 ); } pcbnew/tools/edit_points.h +223 −111 Original line number Diff line number Diff line Loading @@ -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 ) {}; Loading @@ -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 ) Loading @@ -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 ) Loading @@ -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(); Loading @@ -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]; } } 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]; } } /** * 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 ); 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 ) { Loading @@ -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; Loading @@ -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(); Loading @@ -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(); Loading @@ -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; }; Loading pcbnew/tools/point_editor.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -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 ) Loading Loading @@ -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 ) ); } } Loading pcbnew/tools/point_editor.h +0 −1 Original line number Diff line number Diff line Loading @@ -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: Loading Loading
pcbnew/tools/edit_points.cpp +96 −0 Original line number Diff line number Diff line Loading @@ -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 ) { Loading Loading @@ -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 ) ); Loading @@ -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 ); }
pcbnew/tools/edit_points.h +223 −111 Original line number Diff line number Diff line Loading @@ -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 ) {}; Loading @@ -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 ) Loading @@ -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 ) Loading @@ -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(); Loading @@ -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]; } } 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]; } } /** * 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 ); 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 ) { Loading @@ -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; Loading @@ -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(); Loading @@ -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(); Loading @@ -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; }; Loading
pcbnew/tools/point_editor.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -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 ) Loading Loading @@ -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 ) ); } } Loading
pcbnew/tools/point_editor.h +0 −1 Original line number Diff line number Diff line Loading @@ -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: Loading