Fix a Eeschema crash when using a SYMBOL_PREVIEW_WIDGET. Fix also a few draw artifacts.

This commit is contained in:
jean-pierre charras 2018-09-17 11:22:11 +02:00 committed by Jeff Young
parent a6d014d959
commit 4a92a5e628
4 changed files with 61 additions and 36 deletions

View File

@ -150,10 +150,15 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
{
m_viewControls->UpdateScrollbars();
GetParentEDAFrame()->GetScreen()->SetZoom( GetLegacyZoom() );
// Update current zoom settings if the canvas is managed by a EDA frame
// (i.e. not by a preview panel in a dialog)
if( GetParentEDAFrame() && GetParentEDAFrame()->GetScreen() )
{
GetParentEDAFrame()->GetScreen()->SetZoom( GetLegacyZoom() );
VECTOR2D center = GetView()->GetCenter();
GetParentEDAFrame()->SetScrollCenterPosition( wxPoint( center.x, center.y ) );
VECTOR2D center = GetView()->GetCenter();
GetParentEDAFrame()->SetScrollCenterPosition( wxPoint( center.x, center.y ) );
}
// Drawing to a zero-width or zero-height GAL is fraught with peril.
if( GetClientRect().IsEmpty() )
@ -189,7 +194,8 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
if( m_view->IsDirty() )
{
if( m_backend != GAL_TYPE_OPENGL ) // already called in opengl
if( m_backend != GAL_TYPE_OPENGL && // Already called in opengl
m_view->IsTargetDirty( KIGFX::TARGET_NONCACHED ) )
m_gal->ClearScreen();
m_view->ClearTargets();

View File

@ -421,9 +421,6 @@ void SCH_PAINTER::draw( LIB_POLYLINE *aLine, int aLayer )
for( auto p : aLine->GetPolyPoints() )
vtx.push_back ( mapCoords( p ) );
// if( aLine->GetFillMode() == FILLED_WITH_BG_BODYCOLOR || aLine->GetFillMode() == FILLED_SHAPE )
// vtx.push_back( vtx[0] );
m_gal->DrawPolygon( vtx );
}

View File

@ -68,6 +68,8 @@ SYMBOL_PREVIEW_WIDGET::SYMBOL_PREVIEW_WIDGET( wxWindow* aParent, KIWAY& aKiway,
m_statusSizer->ShowItems( false );
SetSizer( outer_sizer );
Connect( wxEVT_SIZE, wxSizeEventHandler( SYMBOL_PREVIEW_WIDGET::onSize ), NULL, this );
}
@ -87,6 +89,42 @@ void SYMBOL_PREVIEW_WIDGET::SetStatusText( wxString const& aText )
}
void SYMBOL_PREVIEW_WIDGET::onSize( wxSizeEvent& aEvent )
{
aEvent.Skip();
if( m_previewItem )
{
fitOnDrawArea();
m_preview->ForceRefresh();
}
}
void SYMBOL_PREVIEW_WIDGET::fitOnDrawArea()
{
if( !m_previewItem )
return;
// set the view scale to fit the item on screen
// Calculate the draw scale to fit the drawing area
KIGFX::VIEW* view = m_preview->GetView();
// Calculate the drawing area size, in internal units, for a scaling factor = 1.0
view->SetScale( 1.0 );
VECTOR2D clientSize = view->ToWorld( m_preview->GetClientSize(), false );
double scale = std::min( fabs( clientSize.x / m_itemBBox.GetWidth() ),
fabs( clientSize.y / m_itemBBox.GetHeight() ) );
// Above calculation will yield an exact fit; add a bit of whitespace around symbol
scale /= 1.2;
// Now fix the best scale
view->SetScale( scale );
view->SetCenter( m_itemBBox.Centre() );
}
void SYMBOL_PREVIEW_WIDGET::DisplaySymbol( const LIB_ID& aSymbolID, int aUnit )
{
KIGFX::VIEW* view = m_preview->GetView();
@ -128,22 +166,11 @@ void SYMBOL_PREVIEW_WIDGET::DisplaySymbol( const LIB_ID& aSymbolID, int aUnit )
view->Add( alias );
m_previewItem = alias;
// Get the symbole size, in internal units
m_itemBBox = alias->GetPart()->GetUnitBoundingBox( aUnit, 0 );
// Calculate the draw scale to fit the drawing area
// First, get the symbole size, in internal units
BOX2I bBox = alias->GetPart()->GetUnitBoundingBox( aUnit, 0 );
// Now calculate the drawing area size, in internal units, for a scaling factor = 1.0
view->SetScale( 1.0 );
VECTOR2D clientSize = view->ToWorld( m_preview->GetClientSize(), false );
double scale = std::min( fabs( clientSize.x / bBox.GetWidth() ),
fabs( clientSize.y / bBox.GetHeight() ) );
// Above calculation will yield an exact fit; add a bit of whitespace around symbol
scale /= 1.2;
// Now fix the best scale
view->SetScale( scale );
view->SetCenter( bBox.Centre() );
fitOnDrawArea();
}
m_preview->ForceRefresh();
@ -177,21 +204,11 @@ void SYMBOL_PREVIEW_WIDGET::DisplayPart( LIB_PART* aPart, int aUnit )
view->Add( aPart );
m_previewItem = aPart;
// Get the symbole size, in internal units
m_itemBBox = aPart->GetUnitBoundingBox( aUnit, 0 );
// Calculate the draw scale to fit the drawing area
// First, get the symbole size, in internal units
BOX2I bBox = aPart->GetUnitBoundingBox( aUnit, 0 );
// Now calculate the drawing area size, in internal units, for a scaling factor = 1.0
view->SetScale( 1.0 );
VECTOR2D clientSize = view->ToWorld( m_preview->GetClientSize(), false );
double scale = std::min( fabs( clientSize.x / bBox.GetWidth() ),
fabs( clientSize.y / bBox.GetHeight() ) );
// Above calculation will yield an exact fit; add a bit of whitespace around symbol
scale /= 1.2;
// Now fix the best scale
view->SetScale( scale );
view->SetCenter( bBox.Centre() );
fitOnDrawArea();
}
m_preview->ForceRefresh();

View File

@ -63,6 +63,10 @@ public:
void DisplayPart( LIB_PART* aPart, int aUnit );
private:
void onSize( wxSizeEvent& aEvent );
void fitOnDrawArea(); // set the view scale to fit the item on screen and center
KIWAY& m_kiway;
KIGFX::GAL_DISPLAY_OPTIONS m_galDisplayOptions;
@ -72,6 +76,7 @@ private:
wxSizer* m_statusSizer;
EDA_ITEM* m_previewItem;
BOX2I m_itemBBox; // The size of the current item
};