From 099f58a100208882c75228f9d89fb57a95534e87 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 6 Mar 2014 17:34:04 +0100 Subject: [PATCH] Added EDIT_LINEs for dragging zone outlines. --- pcbnew/tools/edit_points.cpp | 18 +++++-- pcbnew/tools/edit_points.h | 95 ++++++++++++++++++++++++++++++----- pcbnew/tools/point_editor.cpp | 63 ++++++++++++++++++----- pcbnew/tools/point_editor.h | 3 ++ 4 files changed, 151 insertions(+), 28 deletions(-) diff --git a/pcbnew/tools/edit_points.cpp b/pcbnew/tools/edit_points.cpp index 5e7174e5be..73550418f1 100644 --- a/pcbnew/tools/edit_points.cpp +++ b/pcbnew/tools/edit_points.cpp @@ -39,10 +39,19 @@ EDIT_POINT* EDIT_POINTS::FindPoint( const VECTOR2I& aLocation ) { float size = m_view->ToWorld( EDIT_POINT::POINT_SIZE ); - std::deque::iterator it, itEnd; - for( it = m_points.begin(), itEnd = m_points.end(); it != itEnd; ++it ) + std::deque::iterator pit, pitEnd; + for( pit = m_points.begin(), pitEnd = m_points.end(); pit != pitEnd; ++pit ) { - EDIT_POINT& point = *it; + EDIT_POINT& point = *pit; + + if( point.WithinPoint( aLocation, size ) ) + return &point; + } + + std::deque::iterator lit, litEnd; + for( lit = m_lines.begin(), litEnd = m_lines.end(); lit != litEnd; ++lit ) + { + EDIT_LINE& point = *lit; if( point.WithinPoint( aLocation, size ) ) return &point; @@ -65,5 +74,8 @@ void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const BOOST_FOREACH( const EDIT_POINT& point, m_points ) aGal->DrawRectangle( point.GetPosition() - size / 2, point.GetPosition() + size / 2 ); + BOOST_FOREACH( const EDIT_LINE& line, m_lines ) + aGal->DrawRectangle( line.GetPosition() - size / 2, line.GetPosition() + size / 2 ); + aGal->PopDepth(); } diff --git a/pcbnew/tools/edit_points.h b/pcbnew/tools/edit_points.h index c91bede8ec..3e5d8ecc9b 100644 --- a/pcbnew/tools/edit_points.h +++ b/pcbnew/tools/edit_points.h @@ -52,21 +52,21 @@ class EDIT_POINT { public: EDIT_POINT( const VECTOR2I& aPoint ) : - m_point( aPoint ), m_constraint( NULL ) {}; + m_position( aPoint ), m_constraint( NULL ) {}; - ~EDIT_POINT() + virtual ~EDIT_POINT() { delete m_constraint; } - const VECTOR2I& GetPosition() const + virtual VECTOR2I GetPosition() const { - return m_point; + return m_position; } - void SetPosition( const VECTOR2I& aPosition ) + virtual void SetPosition( const VECTOR2I& aPosition ) { - m_point = aPosition; + m_position = aPosition; } bool WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const @@ -110,18 +110,56 @@ public: bool operator==( const EDIT_POINT& aOther ) const { - return m_point == aOther.m_point; + return m_position == aOther.m_position; } ///> Single point size in pixels static const int POINT_SIZE = 10; -private: - VECTOR2I m_point; +protected: + VECTOR2I m_position; EDIT_POINT_CONSTRAINT* m_constraint; }; +class EDIT_LINE : public EDIT_POINT +{ +public: + EDIT_LINE( EDIT_POINT& aOrigin, EDIT_POINT& aEnd ) : + EDIT_POINT( aOrigin.GetPosition() + ( aEnd.GetPosition() - aOrigin.GetPosition() ) / 2 ), + m_origin( aOrigin ), m_end( aEnd ) + { + } + + virtual VECTOR2I GetPosition() const + { + return m_origin.GetPosition() + ( m_end.GetPosition() - m_origin.GetPosition() ) / 2; + } + + virtual void SetPosition( const VECTOR2I& aPosition ) + { + VECTOR2I difference = aPosition - GetPosition(); + + m_origin.SetPosition( m_origin.GetPosition() + difference ); + m_end.SetPosition( m_end.GetPosition() + difference ); + } + + bool operator==( const EDIT_POINT& aOther ) const + { + return GetPosition() == aOther.GetPosition(); + } + + bool operator==( const EDIT_LINE& aOther ) const + { + return m_origin == aOther.m_origin && m_end == aOther.m_end; + } + +private: + EDIT_POINT& m_origin; + EDIT_POINT& m_end; +}; + + class EDIT_POINTS : public EDA_ITEM { public: @@ -139,14 +177,24 @@ public: return m_parent; } - void Add( const EDIT_POINT& aPoint ) + void AddPoint( const EDIT_POINT& aPoint ) { m_points.push_back( aPoint ); } - void Add( const VECTOR2I& aPoint ) + void AddPoint( const VECTOR2I& aPoint ) { - Add( EDIT_POINT( aPoint ) ); + AddPoint( EDIT_POINT( aPoint ) ); + } + + void AddLine( const EDIT_LINE& aLine ) + { + m_lines.push_back( aLine ); + } + + void AddLine( EDIT_POINT& aOrigin, EDIT_POINT& aEnd ) + { + m_lines.push_back( EDIT_LINE( aOrigin, aEnd ) ); } EDIT_POINT* Previous( const EDIT_POINT& aPoint ) @@ -162,6 +210,17 @@ public: } } + 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; } @@ -178,6 +237,17 @@ public: } } + 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; } @@ -216,6 +286,7 @@ public: private: EDA_ITEM* m_parent; std::deque m_points; + std::deque m_lines; }; diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index e00d72fe1a..6a29061669 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -60,15 +60,15 @@ public: switch( segment->GetShape() ) { case S_SEGMENT: - points->Add( segment->GetStart() ); - points->Add( segment->GetEnd() ); + points->AddPoint( segment->GetStart() ); + points->AddPoint( segment->GetEnd() ); break; case S_ARC: - points->Add( segment->GetCenter() ); // points[0] - points->Add( segment->GetArcStart() ); // points[1] - points->Add( segment->GetArcEnd() ); // points[2] + points->AddPoint( segment->GetCenter() ); // points[0] + points->AddPoint( segment->GetArcStart() ); // points[1] + points->AddPoint( segment->GetArcEnd() ); // points[2] // Set constraints // Arc end has to stay at the same radius as the start @@ -76,8 +76,9 @@ public: break; case S_CIRCLE: - points->Add( segment->GetCenter() ); - points->Add( segment->GetEnd() ); + points->AddPoint( segment->GetCenter() ); + points->AddPoint( segment->GetEnd() ); + break; default: // suppress warnings break; @@ -89,9 +90,17 @@ public: case PCB_ZONE_AREA_T: { const CPolyLine* outline = static_cast( aItem )->Outline(); + int cornersCount = outline->GetCornersCount(); - for( int i = 0; i < outline->GetCornersCount(); ++i ) - points->Add( outline->GetPos( i ) ); + for( int i = 0; i < cornersCount; ++i ) + points->AddPoint( outline->GetPos( i ) ); + + // Lines have to be added after creating edit points, so they use EDIT_POINT references + for( int i = 0; i < cornersCount - 1; ++i ) + points->AddLine( (*points)[i], (*points)[i + 1] ); + + // The one missing line + points->AddLine( (*points)[cornersCount - 1], (*points)[0] ); break; } @@ -147,7 +156,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) Activate(); KIGFX::VIEW_CONTROLS* controls = getViewControls(); - KIGFX::VIEW* view = getView(); // TODO should be updated on canvas switch? + KIGFX::VIEW* view = getView(); PCB_EDIT_FRAME* editFrame = getEditFrame(); EDA_ITEM* item = selection.items.GetPickedItem( 0 ); @@ -210,9 +219,9 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) { 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 ) ); + // Find a proper constraining point for 45 degrees mode + EDIT_POINT constrainer = get45DegConstrainer(); + m_dragPoint->SetConstraint( new EPC_45DEGREE( *m_dragPoint, constrainer ) ); } } else @@ -446,3 +455,31 @@ void POINT_EDITOR::updatePoints() const break; } } + + +EDIT_POINT POINT_EDITOR::get45DegConstrainer() const +{ + EDA_ITEM* item = m_editPoints->GetParent(); + + if( item->Type() == PCB_LINE_T ) + { + const DRAWSEGMENT* segment = static_cast( item ); + { + switch( segment->GetShape() ) + { + case S_SEGMENT: + return *( m_editPoints->Next( *m_dragPoint ) ); // select the other end of line + + case S_ARC: + case S_CIRCLE: + return (*m_editPoints)[0]; // center + + default: // suppress warnings + break; + } + } + } + + // In any other case we may align item to the current cursor position. + return EDIT_POINT( getViewControls()->GetCursorPosition() ); +} diff --git a/pcbnew/tools/point_editor.h b/pcbnew/tools/point_editor.h index 81b55131ba..b465966873 100644 --- a/pcbnew/tools/point_editor.h +++ b/pcbnew/tools/point_editor.h @@ -75,6 +75,9 @@ private: ///> Updates edit points with item's points. void updatePoints() const; + ///> Returns a point that should be used as a constrainer for 45 degrees mode. + EDIT_POINT get45DegConstrainer() const; + ///> Sets up handlers for various events. void setTransitions() {