From 4a92a5e628e9c0f2277fb89cdf9821c8c3a5d796 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Mon, 17 Sep 2018 11:22:11 +0200 Subject: [PATCH] Fix a Eeschema crash when using a SYMBOL_PREVIEW_WIDGET. Fix also a few draw artifacts. --- common/draw_panel_gal.cpp | 14 ++-- eeschema/sch_painter.cpp | 3 - eeschema/widgets/symbol_preview_widget.cpp | 75 +++++++++++++--------- eeschema/widgets/symbol_preview_widget.h | 5 ++ 4 files changed, 61 insertions(+), 36 deletions(-) diff --git a/common/draw_panel_gal.cpp b/common/draw_panel_gal.cpp index 0b0413595d..7ba5d854b5 100644 --- a/common/draw_panel_gal.cpp +++ b/common/draw_panel_gal.cpp @@ -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(); diff --git a/eeschema/sch_painter.cpp b/eeschema/sch_painter.cpp index fe579b8f4d..c1ba3cf4b8 100644 --- a/eeschema/sch_painter.cpp +++ b/eeschema/sch_painter.cpp @@ -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 ); } diff --git a/eeschema/widgets/symbol_preview_widget.cpp b/eeschema/widgets/symbol_preview_widget.cpp index cd9a0d8b83..d994809e79 100644 --- a/eeschema/widgets/symbol_preview_widget.cpp +++ b/eeschema/widgets/symbol_preview_widget.cpp @@ -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(); diff --git a/eeschema/widgets/symbol_preview_widget.h b/eeschema/widgets/symbol_preview_widget.h index c817b1fe46..581ed84e7e 100644 --- a/eeschema/widgets/symbol_preview_widget.h +++ b/eeschema/widgets/symbol_preview_widget.h @@ -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 };