Page layout: rework and fix a few issues.

* rename WS_DRAW_ITEM_POLYGON to WS_DRAW_ITEM_POLYPOLYGONS (better name)
* use SHAPE_POLY_SET instead of std::vector(<wxPoint> to manage the set of polygons.
It also remove duplicate code related to HitTest and bounding box.
* fix HitTest and WS_DRAW_ITEM_POLYGON highlight.
This commit is contained in:
jean-pierre charras 2019-06-13 13:23:39 +02:00
parent c47f97e02f
commit f135ec47fa
7 changed files with 96 additions and 88 deletions

View File

@ -422,27 +422,30 @@ void WS_DATA_ITEM_POLYGONS::SyncDrawItems( WS_DRAW_ITEM_LIST* aCollector, KIGFX:
if( j && !IsInsidePage( j ) )
continue;
int pensize = GetPenSizeUi();
auto poly_shape = new WS_DRAW_ITEM_POLYPOLYGONS( this, j, GetStartPosUi( j ), pensize );
poly_shape->SetFlags( itemFlags[ j ] );
m_drawItems.push_back( poly_shape );
// Transfer all outlines (basic polygons)
SHAPE_POLY_SET& polygons = poly_shape->GetPolygons();
for( int kk = 0; kk < GetPolyCount(); kk++ )
{
const bool fill = true;
int pensize = GetPenSizeUi();
auto poly = new WS_DRAW_ITEM_POLYGON( this, j, GetStartPosUi( j ), fill, pensize );
poly->SetFlags( itemFlags[ j ] );
m_drawItems.push_back( poly );
if( aCollector )
aCollector->Append( poly );
if( aView )
aView->Add( poly );
// Create polygon outline
// Create new outline
unsigned ist = GetPolyIndexStart( kk );
unsigned iend = GetPolyIndexEnd( kk );
polygons.NewOutline();
while( ist <= iend )
poly->m_Corners.push_back( GetCornerPositionUi( ist++, j ) );
polygons.Append( GetCornerPositionUi( ist++, j ) );
}
if( aCollector )
aCollector->Append( poly_shape );
if( aView )
aView->Add( poly_shape );
}
}

View File

@ -188,54 +188,48 @@ wxString WS_DRAW_ITEM_TEXT::GetSelectMenuText( EDA_UNITS_T aUnits ) const
}
// ============================ POLYGON ==============================
// ============================ POLYGON
void WS_DRAW_ITEM_POLYGON::PrintWsItem( wxDC* aDC, const wxPoint& aOffset, COLOR4D aColor )
void WS_DRAW_ITEM_POLYPOLYGONS::PrintWsItem( wxDC* aDC, const wxPoint& aOffset, COLOR4D aColor )
{
std::vector<wxPoint> points_moved;
wxPoint *points;
if( aOffset.x || aOffset.y )
for( int idx = 0; idx < m_Polygons.OutlineCount(); ++idx )
{
for( auto point: m_Corners )
points_moved.push_back( point + aOffset );
points_moved.clear();
SHAPE_LINE_CHAIN& outline = m_Polygons.Outline( idx );
points = &points_moved[0];
}
else
{
points = &m_Corners[0];
}
for( int ii = 0; ii < outline.PointCount(); ii++ )
points_moved.push_back( wxPoint( outline.Point( ii ).x + aOffset.x,
outline.Point( ii ).y + aOffset.y ) );
GRPoly( nullptr, aDC, m_Corners.size(), points, IsFilled() ? FILLED_SHAPE : NO_FILL,
GetPenWidth(), aColor, aColor );
GRPoly( nullptr, aDC, points_moved.size(), &points_moved[0], FILLED_SHAPE,
GetPenWidth(), aColor, aColor );
}
}
const EDA_RECT WS_DRAW_ITEM_POLYGON::GetBoundingBox() const
const EDA_RECT WS_DRAW_ITEM_POLYPOLYGONS::GetBoundingBox() const
{
EDA_RECT rect( GetPosition(), wxSize( 0, 0 ) );
for( wxPoint corner : m_Corners )
rect.Merge( corner );
EDA_RECT rect;
BOX2I box = m_Polygons.BBox();
rect.SetX( box.GetX() );
rect.SetY( box.GetY() );
rect.SetWidth( box.GetWidth() );
rect.SetHeight( box.GetHeight() );
printf("bbox %f %f %f %f\n",box.GetX()/1e3,box.GetY()/1e3,box.GetWidth()/1e3,box.GetHeight()/1e3);fflush(0);
return rect;
}
bool WS_DRAW_ITEM_POLYGON::HitTest( const wxPoint& aPosition, int aAccuracy ) const
bool WS_DRAW_ITEM_POLYPOLYGONS::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
for( unsigned ii = 1; ii < m_Corners.size(); ii++ )
{
if( TestSegmentHit( aPosition, m_Corners[ii - 1], m_Corners[ii], aAccuracy ) )
return true;
}
return false;
return m_Polygons.Contains( aPosition );
}
bool WS_DRAW_ITEM_POLYGON::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
bool WS_DRAW_ITEM_POLYPOLYGONS::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
EDA_RECT sel = aRect;
@ -249,24 +243,32 @@ bool WS_DRAW_ITEM_POLYGON::HitTest( const EDA_RECT& aRect, bool aContained, int
if( !sel.Intersects( GetBoundingBox() ) )
return false;
int count = m_Corners.size();
for( int ii = 0; ii < count; ii++ )
for( int idx = 0; idx < m_Polygons.OutlineCount(); ++idx )
{
// Test if the point is within aRect
if( sel.Contains( m_Corners[ ii ] ) )
return true;
const SHAPE_LINE_CHAIN& outline = m_Polygons.COutline( idx );
// Test if this edge intersects aRect
if( sel.Intersects( m_Corners[ ii ], m_Corners[ (ii+1) % count ] ) )
return true;
for( int ii = 0; ii < outline.PointCount(); ii++ )
{
wxPoint corner( outline.CPoint( ii ).x, outline.CPoint( ii ).y );
// Test if the point is within aRect
if( sel.Contains( corner ) )
return true;
// Test if this edge intersects aRect
int ii_next = (ii+1) % outline.PointCount();
wxPoint next_corner( outline.CPoint( ii_next ).x, outline.CPoint( ii_next ).y );
if( sel.Intersects( corner, next_corner ) )
return true;
}
}
return false;
}
wxString WS_DRAW_ITEM_POLYGON::GetSelectMenuText( EDA_UNITS_T aUnits ) const
wxString WS_DRAW_ITEM_POLYPOLYGONS::GetSelectMenuText( EDA_UNITS_T aUnits ) const
{
return wxString::Format( _( "Imported shape at (%s, %s)" ),
MessageTextFromValue( aUnits, GetPosition().x ),

View File

@ -243,7 +243,7 @@ bool KIGFX::WS_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
switch( item->Type() )
{
case WSG_LINE_T: draw( (WS_DRAW_ITEM_LINE*) item, aLayer ); break;
case WSG_POLY_T: draw( (WS_DRAW_ITEM_POLYGON*) item, aLayer ); break;
case WSG_POLY_T: draw( (WS_DRAW_ITEM_POLYPOLYGONS*) item, aLayer ); break;
case WSG_RECT_T: draw( (WS_DRAW_ITEM_RECT*) item, aLayer ); break;
case WSG_TEXT_T: draw( (WS_DRAW_ITEM_TEXT*) item, aLayer ); break;
case WSG_BITMAP_T: draw( (WS_DRAW_ITEM_BITMAP*) item, aLayer ); break;
@ -275,28 +275,18 @@ void KIGFX::WS_PAINTER::draw( const WS_DRAW_ITEM_RECT* aItem, int aLayer ) const
}
void KIGFX::WS_PAINTER::draw( const WS_DRAW_ITEM_POLYGON* aItem, int aLayer ) const
void KIGFX::WS_PAINTER::draw( const WS_DRAW_ITEM_POLYPOLYGONS* aItem, int aLayer ) const
{
std::deque<VECTOR2D> corners;
for( wxPoint point : aItem->m_Corners )
{
corners.push_back( VECTOR2D( point ) );
}
m_gal->SetFillColor( m_renderSettings.GetColor( aItem, aLayer ) );
m_gal->SetIsFill( true );
m_gal->SetIsStroke( false );
if( aItem->IsFilled() )
WS_DRAW_ITEM_POLYPOLYGONS* item = (WS_DRAW_ITEM_POLYPOLYGONS*)aItem;
for( int idx = 0; idx < item->GetPolygons().OutlineCount(); ++idx )
{
m_gal->SetFillColor( m_renderSettings.GetColor( aItem, aLayer ) );
m_gal->SetIsFill( true );
m_gal->SetIsStroke( false );
m_gal->DrawPolygon( corners );
}
else
{
m_gal->SetStrokeColor( m_renderSettings.GetColor( aItem, aLayer ) );
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
m_gal->SetLineWidth( aItem->GetPenWidth() );
m_gal->DrawPolyline( corners );
SHAPE_LINE_CHAIN& outline = item->GetPolygons().Outline( idx );
m_gal->DrawPolygon( outline );
}
}

View File

@ -117,9 +117,20 @@ void PlotWorkSheet( PLOTTER* plotter, const TITLE_BLOCK& aTitleBlock,
case WSG_POLY_T:
{
WS_DRAW_ITEM_POLYGON* poly = (WS_DRAW_ITEM_POLYGON*) item;
plotter->PlotPoly( poly->m_Corners, poly->IsFilled() ? FILLED_SHAPE : NO_FILL,
poly->GetPenWidth() );
WS_DRAW_ITEM_POLYPOLYGONS* poly = (WS_DRAW_ITEM_POLYPOLYGONS*) item;
std::vector<wxPoint> points;
for( int idx = 0; idx < poly->GetPolygons().OutlineCount(); ++idx )
{
points.clear();
SHAPE_LINE_CHAIN& outline = poly->GetPolygons().Outline( idx );
for( int ii = 0; ii < outline.PointCount(); ii++ )
points.push_back( wxPoint( outline.Point( ii ).x ,
outline.Point( ii ).y ) );
plotter->PlotPoly( points, FILLED_SHAPE, poly->GetPenWidth() );
}
}
break;

View File

@ -1,8 +1,8 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2014 KiCad Developers, see CHANGELOG.TXT for contributors.
* Copyright (C) 2013-2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -215,7 +215,7 @@ public:
class WS_DATA_ITEM_POLYGONS : public WS_DATA_ITEM
{
public:
double m_Orient; // Orientation in degrees
double m_Orient; // Orientation in degrees
std::vector<DPOINT> m_Corners; // corner list
private:

View File

@ -30,6 +30,7 @@
#include <eda_text.h>
#include <bitmap_base.h>
#include "msgpanel.h"
#include <geometry/shape_poly_set.h>
class WS_DATA_ITEM;
class TITLE_BLOCK;
@ -139,32 +140,32 @@ public:
};
// This class draws a polygon
class WS_DRAW_ITEM_POLYGON : public WS_DRAW_ITEM_BASE
class WS_DRAW_ITEM_POLYPOLYGONS : public WS_DRAW_ITEM_BASE
{
wxPoint m_pos; // position of reference point, from the
// WS_DATA_ITEM_POLYGONS parent
// (used only in page layout editor to draw anchors)
int m_penWidth;
bool m_fill;
public:
std::vector <wxPoint> m_Corners;
/** The list of polygons. Because these polygons are only for drawing purposes,
* each polygon is expected having no holes, jusst a main outline
*/
SHAPE_POLY_SET m_Polygons;
public:
WS_DRAW_ITEM_POLYGON( WS_DATA_ITEM* aPeer, int aIndex, wxPoint aPos, bool aFill,
int aPenWidth ) :
WS_DRAW_ITEM_POLYPOLYGONS( WS_DATA_ITEM* aPeer, int aIndex, wxPoint aPos, int aPenWidth ) :
WS_DRAW_ITEM_BASE( aPeer, aIndex, WSG_POLY_T )
{
m_penWidth = aPenWidth;
m_fill = aFill;
m_pos = aPos;
}
virtual wxString GetClass() const override { return wxT( "WS_DRAW_ITEM_POLYGON" ); }
virtual wxString GetClass() const override { return wxT( "WS_DRAW_ITEM_POLYPOLYGONS" ); }
// Accessors:
SHAPE_POLY_SET& GetPolygons() { return m_Polygons; }
int GetPenWidth() const { return m_penWidth; }
bool IsFilled() const { return m_fill; }
const wxPoint GetPosition() const override { return m_pos; }
void SetPosition( wxPoint aPos ) override { m_pos = aPos; }
@ -224,7 +225,8 @@ public:
// This class draws a rectangle with thick segment showing the page limits
// and a marker showing the coord origin
// and a marker showing the coord origin. This only a draw item only.
// Therefore m_peer ( the parent WS_DATA_ITEM item in the WS_DATA_MODEL) is always a nullptr.
class WS_DRAW_ITEM_PAGE : public WS_DRAW_ITEM_BASE
{
wxPoint m_markerPos; // position of the marker

View File

@ -116,7 +116,7 @@ public:
private:
void draw( const WS_DRAW_ITEM_LINE* aItem, int aLayer ) const;
void draw( const WS_DRAW_ITEM_RECT* aItem, int aLayer ) const;
void draw( const WS_DRAW_ITEM_POLYGON* aItem, int aLayer ) const;
void draw( const WS_DRAW_ITEM_POLYPOLYGONS* aItem, int aLayer ) const;
void draw( const WS_DRAW_ITEM_TEXT* aItem, int aLayer ) const;
void draw( const WS_DRAW_ITEM_BITMAP* aItem, int aLayer ) const;
void draw( const WS_DRAW_ITEM_PAGE* aItem, int aLayer ) const;