Commit 88a0311a authored by Maciej Suminski's avatar Maciej Suminski

Added EDIT_LINEs for dragging zone outlines.

parent 8c43c216
......@@ -39,10 +39,19 @@ EDIT_POINT* EDIT_POINTS::FindPoint( const VECTOR2I& aLocation )
{
float size = m_view->ToWorld( EDIT_POINT::POINT_SIZE );
std::deque<EDIT_POINT>::iterator it, itEnd;
for( it = m_points.begin(), itEnd = m_points.end(); it != itEnd; ++it )
std::deque<EDIT_POINT>::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<EDIT_LINE>::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();
}
......@@ -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 )
{
AddPoint( EDIT_POINT( aPoint ) );
}
void AddLine( const EDIT_LINE& aLine )
{
Add( EDIT_POINT( aPoint ) );
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<EDIT_POINT> m_points;
std::deque<EDIT_LINE> m_lines;
};
......
......@@ -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<const ZONE_CONTAINER*>( aItem )->Outline();
int cornersCount = outline->GetCornersCount();
for( int i = 0; i < cornersCount; ++i )
points->AddPoint( outline->GetPos( i ) );
for( int i = 0; i < outline->GetCornersCount(); ++i )
points->Add( 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<PCB_EDIT_FRAME>();
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<const DRAWSEGMENT*>( 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() );
}
......@@ -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()
{
......
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