diff --git a/pcbnew/tools/edit_points.cpp b/pcbnew/tools/edit_points.cpp index 5efe90bae0..5e7174e5be 100644 --- a/pcbnew/tools/edit_points.cpp +++ b/pcbnew/tools/edit_points.cpp @@ -35,11 +35,6 @@ EDIT_POINTS::EDIT_POINTS( EDA_ITEM* aParent ) : } -EDIT_POINTS::~EDIT_POINTS() -{ -} - - EDIT_POINT* EDIT_POINTS::FindPoint( const VECTOR2I& aLocation ) { float size = m_view->ToWorld( EDIT_POINT::POINT_SIZE ); @@ -59,7 +54,7 @@ EDIT_POINT* EDIT_POINTS::FindPoint( const VECTOR2I& aLocation ) void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const { - aGal->SetFillColor( KIGFX::COLOR4D( 1.0, 1.0, 1.0, 1.0 ) ); // TODO dynamic color depending on parent's color + aGal->SetFillColor( KIGFX::COLOR4D( 1.0, 1.0, 1.0, 1.0 ) ); aGal->SetIsFill( true ); aGal->SetIsStroke( false ); aGal->PushDepth(); diff --git a/pcbnew/tools/edit_points.h b/pcbnew/tools/edit_points.h index e9a444286d..c91bede8ec 100644 --- a/pcbnew/tools/edit_points.h +++ b/pcbnew/tools/edit_points.h @@ -80,10 +80,13 @@ public: void SetConstraint( EDIT_POINT_CONSTRAINT* aConstraint ) { + if( m_constraint ) + delete m_constraint; + m_constraint = aConstraint; } - void ClearConstraint( EDIT_POINT_CONSTRAINT* aConstraint ) + void ClearConstraint() { delete m_constraint; m_constraint = NULL; @@ -94,12 +97,22 @@ public: return m_constraint; } + bool IsConstrained() const + { + return m_constraint != NULL; + } + void ApplyConstraint() { if( m_constraint ) m_constraint->Apply(); } + bool operator==( const EDIT_POINT& aOther ) const + { + return m_point == aOther.m_point; + } + ///> Single point size in pixels static const int POINT_SIZE = 10; @@ -113,7 +126,6 @@ class EDIT_POINTS : public EDA_ITEM { public: EDIT_POINTS( EDA_ITEM* aParent ); - ~EDIT_POINTS(); /** * Function FindPoint @@ -134,7 +146,39 @@ public: void Add( const VECTOR2I& aPoint ) { - m_points.push_back( EDIT_POINT( aPoint ) ); + Add( EDIT_POINT( aPoint ) ); + } + + 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]; + } + } + + 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]; + } + } + + return NULL; } EDIT_POINT& operator[]( unsigned int aIndex ) @@ -182,8 +226,6 @@ public: EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) {} - virtual ~EPC_VERTICAL() {}; - virtual void Apply() { VECTOR2I point = m_constrained.GetPosition(); @@ -208,8 +250,6 @@ public: EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) {} - virtual ~EPC_HORIZONTAL() {}; - virtual void Apply() { VECTOR2I point = m_constrained.GetPosition(); @@ -222,6 +262,31 @@ private: }; +class EPC_45DEGREE : public EDIT_POINT_CONSTRAINT +{ +public: + 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 ); + } + +private: + const EDIT_POINT& m_constrainer; +}; + + class EPC_CIRCLE : public EDIT_POINT_CONSTRAINT { public: diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index cf78c7d89d..e00d72fe1a 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include "common_actions.h" @@ -96,6 +97,7 @@ public: } default: + points.reset(); break; } @@ -139,19 +141,27 @@ bool POINT_EDITOR::Init() int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) { const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - KIGFX::VIEW_CONTROLS* controls = getViewControls(); if( selection.Size() == 1 ) { + Activate(); + + KIGFX::VIEW_CONTROLS* controls = getViewControls(); + KIGFX::VIEW* view = getView(); // TODO should be updated on canvas switch? PCB_EDIT_FRAME* editFrame = getEditFrame(); EDA_ITEM* item = selection.items.GetPickedItem( 0 ); + m_editPoints = EDIT_POINTS_FACTORY::Make( item ); - m_toolMgr->GetView()->Add( m_editPoints.get() ); + if( !m_editPoints ) + { + setTransitions(); + return 0; + } + + view->Add( m_editPoints.get() ); m_dragPoint = NULL; bool modified = false; - Activate(); - // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { @@ -196,6 +206,20 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) modified = true; } + if( evt->Modifier( MD_CTRL ) ) // 45 degrees mode + { + if( !m_dragPoint->IsConstrained() ) + { + // Find the previous point to be used as constrainer + EDIT_POINT* constrainer = m_editPoints->Previous( *m_dragPoint ); + m_dragPoint->SetConstraint( new EPC_45DEGREE( *m_dragPoint, *constrainer ) ); + } + } + else + { + m_dragPoint->ClearConstraint(); + } + m_dragPoint->SetPosition( controls->GetCursorPosition() ); m_dragPoint->ApplyConstraint(); updateItem(); @@ -238,14 +262,14 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) { finishItem(); item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - m_toolMgr->GetView()->Remove( m_editPoints.get() ); + view->Remove( m_editPoints.get() ); m_editPoints.reset(); } - } - controls->ShowCursor( false ); - controls->SetAutoPan( false ); - controls->SetSnapping( false ); + controls->ShowCursor( false ); + controls->SetAutoPan( false ); + controls->SetSnapping( false ); + } setTransitions();