From e339007d22279261968e64f69754b652c8c9f968 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Thu, 10 May 2018 12:49:20 +0200 Subject: [PATCH] 3D viewer: fix some issues when opened from a frame and changes are made in a other frame: * Refresh the view only when changes are made in the caller frame. * Allows recreate a new instances when try to open the 3D view from a frame taht is not the initial caller * Remove duplicate code in kicad frames. --- 3d-viewer/3d_viewer/eda_3d_viewer.cpp | 23 ++++------ 3d-viewer/3d_viewer/eda_3d_viewer.h | 9 ++-- cvpcb/CMakeLists.txt | 2 +- cvpcb/display_footprints_frame.cpp | 34 ++------------ include/pcb_base_frame.h | 24 ++++++++++ pcbnew/footprint_edit_frame.cpp | 31 ++----------- pcbnew/footprint_editor_utils.cpp | 24 ++-------- pcbnew/footprint_viewer_frame.cpp | 18 +------- pcbnew/pcb_base_frame.cpp | 66 +++++++++++++++++++++++++++ pcbnew/pcb_edit_frame.cpp | 29 ++---------- qa/pcb_test_window/CMakeLists.txt | 1 + 11 files changed, 118 insertions(+), 143 deletions(-) diff --git a/3d-viewer/3d_viewer/eda_3d_viewer.cpp b/3d-viewer/3d_viewer/eda_3d_viewer.cpp index e730bab572..a1b33aa485 100644 --- a/3d-viewer/3d_viewer/eda_3d_viewer.cpp +++ b/3d-viewer/3d_viewer/eda_3d_viewer.cpp @@ -141,24 +141,17 @@ BEGIN_EVENT_TABLE( EDA_3D_VIEWER, EDA_BASE_FRAME ) END_EVENT_TABLE() -EDA_3D_VIEWER::EDA_3D_VIEWER( KIWAY *aKiway, - PCB_BASE_FRAME *aParent, - const wxString &aTitle, - long style ) : +EDA_3D_VIEWER::EDA_3D_VIEWER( KIWAY *aKiway, PCB_BASE_FRAME *aParent, + const wxString &aTitle, long style ) : - KIWAY_PLAYER( aKiway, - aParent, - FRAME_PCB_DISPLAY3D, - aTitle, - wxDefaultPosition, - wxDefaultSize, - style, - VIEWER3D_FRAMENAME ) + KIWAY_PLAYER( aKiway, aParent, + FRAME_PCB_DISPLAY3D, aTitle, + wxDefaultPosition, wxDefaultSize, + style, VIEWER3D_FRAMENAME ) { wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER::EDA_3D_VIEWER %s" ), aTitle ); m_canvas = NULL; - m_defaultFileName = ""; // Give it an icon wxIcon icon; @@ -216,7 +209,7 @@ EDA_3D_VIEWER::EDA_3D_VIEWER( KIWAY *aKiway, EDA_3D_VIEWER::~EDA_3D_VIEWER() { m_mainToolBar->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( EDA_3D_VIEWER::OnKeyEvent ), NULL, this ); - + m_auimgr.UnInit(); // m_canvas delete will be called by wxWidget manager @@ -946,7 +939,7 @@ void EDA_3D_VIEWER::takeScreenshot( wxCommandEvent& event ) fn.SetExt( file_ext ); fullFileName = EDA_FILE_SELECTOR( _( "3D Image File Name:" ), fn.GetPath(), - m_defaultFileName, file_ext, mask, this, + m_defaultSaveScreenshotFileName, file_ext, mask, this, wxFD_SAVE | wxFD_OVERWRITE_PROMPT, true ); if( fullFileName.IsEmpty() ) diff --git a/3d-viewer/3d_viewer/eda_3d_viewer.h b/3d-viewer/3d_viewer/eda_3d_viewer.h index a18f46374d..1f4e37ad08 100644 --- a/3d-viewer/3d_viewer/eda_3d_viewer.h +++ b/3d-viewer/3d_viewer/eda_3d_viewer.h @@ -52,8 +52,7 @@ class EDA_3D_VIEWER : public KIWAY_PLAYER public: - EDA_3D_VIEWER( KIWAY *aKiway, - PCB_BASE_FRAME *aParent, + EDA_3D_VIEWER( KIWAY *aKiway, PCB_BASE_FRAME *aParent, const wxString &aTitle, long style = KICAD_DEFAULT_3D_DRAWFRAME_STYLE ); @@ -93,14 +92,14 @@ class EDA_3D_VIEWER : public KIWAY_PLAYER void SetDefaultFileName( const wxString &aFn ) { wxFileName fn( aFn ); - m_defaultFileName = fn.GetName(); + m_defaultSaveScreenshotFileName = fn.GetName(); } /** * Function GetDefaultFileName * @return the default suggested file name */ - const wxString &GetDefaultFileName() const { return m_defaultFileName; } + const wxString &GetDefaultFileName() const { return m_defaultSaveScreenshotFileName; } /** * Function GetSettings @@ -226,7 +225,7 @@ class EDA_3D_VIEWER : public KIWAY_PLAYER /** * Filename to propose for save a screenshot */ - wxString m_defaultFileName; + wxString m_defaultSaveScreenshotFileName; /** * The canvas where the openGL context will be rendered diff --git a/cvpcb/CMakeLists.txt b/cvpcb/CMakeLists.txt index 9cc54d669d..09b2a7388b 100644 --- a/cvpcb/CMakeLists.txt +++ b/cvpcb/CMakeLists.txt @@ -142,10 +142,10 @@ set_target_properties( cvpcb_kiface PROPERTIES SUFFIX ${KIFACE_SUFFIX} ) target_link_libraries( cvpcb_kiface - 3d-viewer pcbcommon pcad2kicadpcb common + 3d-viewer bitmaps polygon gal diff --git a/cvpcb/display_footprints_frame.cpp b/cvpcb/display_footprints_frame.cpp index 9d80687b4f..a0adfb2f25 100644 --- a/cvpcb/display_footprints_frame.cpp +++ b/cvpcb/display_footprints_frame.cpp @@ -149,12 +149,6 @@ DISPLAY_FOOTPRINTS_FRAME::~DISPLAY_FOOTPRINTS_FRAME() void DISPLAY_FOOTPRINTS_FRAME::OnCloseWindow( wxCloseEvent& event ) { - EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame(); - - if( draw3DFrame ) - draw3DFrame->Close( true ); - - Destroy(); } @@ -392,27 +386,8 @@ bool DISPLAY_FOOTPRINTS_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPositi void DISPLAY_FOOTPRINTS_FRAME::Show3D_Frame( wxCommandEvent& event ) { - EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame(); - - if( draw3DFrame ) - { - // Raising the window does not show the window on Windows if iconized. - // This should work on any platform. - if( draw3DFrame->IsIconized() ) - draw3DFrame->Iconize( false ); - - draw3DFrame->Raise(); - - // Raising the window does not set the focus on Linux. This should work on any platform. - if( wxWindow::FindFocus() != draw3DFrame ) - draw3DFrame->SetFocus(); - - return; - } - - draw3DFrame = new EDA_3D_VIEWER( &Kiway(), this, _( "3D Viewer" ) ); - draw3DFrame->Raise(); // Needed with some Window Managers - draw3DFrame->Show( true ); + bool forceRecreateIfNotOwner = true; + CreateAndShow3D_Frame( forceRecreateIfNotOwner ); } @@ -543,10 +518,7 @@ void DISPLAY_FOOTPRINTS_FRAME::InitDisplay() GetCanvas()->Refresh(); - EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame(); - - if( draw3DFrame ) - draw3DFrame->NewDisplay( true ); + Update3DView(); } diff --git a/include/pcb_base_frame.h b/include/pcb_base_frame.h index e87ba70836..52f9532173 100644 --- a/include/pcb_base_frame.h +++ b/include/pcb_base_frame.h @@ -106,6 +106,15 @@ public: */ EDA_3D_VIEWER* Get3DViewerFrame(); + /** + * Update the 3D view, if the viewer is opened by this frame + * @param aTitle = the new title of the 3D frame, or nullptr + * to do not change the frame title + * @return false if the 3D view cannot be updated (because the + * owner of the viewer is not this frame) + */ + bool Update3DView( const wxString* aTitle = nullptr ); + /** * Function LoadFootprint * attempts to load \a aFootprintId from the footprint library table. @@ -218,8 +227,23 @@ public: */ const wxString GetZoomLevelIndicator() const override; + /** + * Shows the 3D view frame. + * If it does not exist, it is created. + * If it exists, and if I am the owner, it is bring to the foreground + */ virtual void Show3D_Frame( wxCommandEvent& event ); + /** + * Shows the 3D view frame. + * If it does not exist, it is created. + * If it exists, it is bring to the foreground + * @param aForceRecreateIfNotOwner = true to recreate the 3D frame viewer, + * when the owner is not me + * @return true if it is shown with me as owner + */ + virtual bool CreateAndShow3D_Frame( bool aForceRecreateIfNotOwner ); + // Read/write functions: EDA_ITEM* ReadDrawSegmentDescr( LINE_READER* aReader ); int ReadListeSegmentDescr( LINE_READER* aReader, diff --git a/pcbnew/footprint_edit_frame.cpp b/pcbnew/footprint_edit_frame.cpp index 0fb0a119b4..6787661cd6 100644 --- a/pcbnew/footprint_edit_frame.cpp +++ b/pcbnew/footprint_edit_frame.cpp @@ -686,27 +686,8 @@ void FOOTPRINT_EDIT_FRAME::OnUpdateSelectCurrentLib( wxUpdateUIEvent& aEvent ) void FOOTPRINT_EDIT_FRAME::Show3D_Frame( wxCommandEvent& event ) { - EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame(); - - if( draw3DFrame ) - { - // Raising the window does not show the window on Windows if iconized. - // This should work on any platform. - if( draw3DFrame->IsIconized() ) - draw3DFrame->Iconize( false ); - - draw3DFrame->Raise(); - - // Raising the window does not set the focus on Linux. This should work on any platform. - if( wxWindow::FindFocus() != draw3DFrame ) - draw3DFrame->SetFocus(); - - return; - } - - draw3DFrame = new EDA_3D_VIEWER( &Kiway(), this, _( "3D Viewer" ) ); - draw3DFrame->Raise(); // Needed with some Window Managers - draw3DFrame->Show( true ); + bool forceRecreateIfNotOwner = true; + CreateAndShow3D_Frame( forceRecreateIfNotOwner ); } @@ -748,13 +729,7 @@ bool FOOTPRINT_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, void FOOTPRINT_EDIT_FRAME::OnModify() { PCB_BASE_FRAME::OnModify(); - - EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame(); - - if( draw3DFrame ) - { - draw3DFrame->NewDisplay( true ); - } + Update3DView(); } diff --git a/pcbnew/footprint_editor_utils.cpp b/pcbnew/footprint_editor_utils.cpp index ee52422b31..b8f71b3df5 100644 --- a/pcbnew/footprint_editor_utils.cpp +++ b/pcbnew/footprint_editor_utils.cpp @@ -186,10 +186,7 @@ void FOOTPRINT_EDIT_FRAME::LoadModuleFromBoard( wxCommandEvent& event ) GetScreen()->ClearUndoRedoList(); GetScreen()->ClrModify(); - EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame(); - - if( draw3DFrame ) - draw3DFrame->NewDisplay( true ); + Update3DView(); } @@ -372,10 +369,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) updateView(); m_canvas->Refresh(); - EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame(); - - if( draw3DFrame ) - draw3DFrame->NewDisplay( true ); + Update3DView(); GetScreen()->ClrModify(); } @@ -495,12 +489,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) GetScreen()->ClrModify(); Zoom_Automatique( false ); m_canvas->Refresh(); - { - EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame(); - - if( draw3DFrame ) - draw3DFrame->NewDisplay( true ); - } + Update3DView(); break; @@ -567,12 +556,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) Zoom_Automatique( false ); - { - EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame(); - - if( draw3DFrame ) - draw3DFrame->NewDisplay( true ); - } + Update3DView(); GetScreen()->ClrModify(); diff --git a/pcbnew/footprint_viewer_frame.cpp b/pcbnew/footprint_viewer_frame.cpp index 6f5dd9e096..11e779bcbd 100644 --- a/pcbnew/footprint_viewer_frame.cpp +++ b/pcbnew/footprint_viewer_frame.cpp @@ -314,14 +314,9 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent FOOTPRINT_VIEWER_FRAME::~FOOTPRINT_VIEWER_FRAME() { - EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame(); - - if( draw3DFrame ) - draw3DFrame->Destroy(); } - void FOOTPRINT_VIEWER_FRAME::OnCloseWindow( wxCloseEvent& Event ) { DBG(printf( "%s:\n", __func__ );) @@ -706,21 +701,10 @@ void FOOTPRINT_VIEWER_FRAME::Show3D_Frame( wxCommandEvent& event ) void FOOTPRINT_VIEWER_FRAME::Update3D_Frame( bool aForceReloadFootprint ) { - EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame(); - - if( draw3DFrame == NULL ) - return; - wxString title = wxString::Format( _( "3D Viewer" ) + wxT( " \u2014 %s" ), getCurFootprintName() ); - draw3DFrame->SetTitle( title ); - - if( aForceReloadFootprint ) - { - // Force 3D screen refresh immediately - draw3DFrame->NewDisplay( true ); - } + Update3DView( &title ); } diff --git a/pcbnew/pcb_base_frame.cpp b/pcbnew/pcb_base_frame.cpp index 0684aaec1e..02e6db0f71 100644 --- a/pcbnew/pcb_base_frame.cpp +++ b/pcbnew/pcb_base_frame.cpp @@ -137,6 +137,30 @@ EDA_3D_VIEWER* PCB_BASE_FRAME::Get3DViewerFrame() } +bool PCB_BASE_FRAME::Update3DView( const wxString* aTitle ) +{ + // Update the 3D view only if the viewer is opened by this frame + EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame(); + + if( draw3DFrame == NULL ) + return false; + + // Ensure the viewer was created by me, and not by an other editor: + PCB_BASE_FRAME* owner = draw3DFrame->Parent(); + + // if I am not the owner, do not use the current viewer instance + if( this != owner ) + return false; + + if( aTitle ) + draw3DFrame->SetTitle( *aTitle ); + + draw3DFrame->NewDisplay( true ); + + return true; +} + + FP_LIB_TABLE* PROJECT::PcbFootprintLibs() { // This is a lazy loading function, it loads the project specific table when @@ -406,6 +430,48 @@ void PCB_BASE_FRAME::Show3D_Frame( wxCommandEvent& event ) } +bool PCB_BASE_FRAME::CreateAndShow3D_Frame( bool aForceRecreateIfNotOwner ) +{ + EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame(); + + // Ensure the viewer was created by me, and not by an other editor: + PCB_BASE_FRAME* owner = draw3DFrame ? draw3DFrame->Parent() : nullptr; + + // if I am not the owner, do not use the current viewer instance + if( draw3DFrame && this != owner ) + { + if( aForceRecreateIfNotOwner ) + { + draw3DFrame->Destroy(); + draw3DFrame = nullptr; + } + else + return false; + } + + if( !draw3DFrame ) + { + draw3DFrame = new EDA_3D_VIEWER( &Kiway(), this, _( "3D Viewer" ) ); + draw3DFrame->Raise(); // Needed with some Window Managers + draw3DFrame->Show( true ); + return true; + } + + // Raising the window does not show the window on Windows if iconized. + // This should work on any platform. + if( draw3DFrame->IsIconized() ) + draw3DFrame->Iconize( false ); + + draw3DFrame->Raise(); + + // Raising the window does not set the focus on Linux. This should work on any platform. + if( wxWindow::FindFocus() != draw3DFrame ) + draw3DFrame->SetFocus(); + + return true; +} + + // Note: virtual, overridden in PCB_EDIT_FRAME; void PCB_BASE_FRAME::SwitchLayer( wxDC* DC, PCB_LAYER_ID layer ) { diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index 2279acc4d0..e2730093d7 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -723,28 +723,8 @@ void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event ) void PCB_EDIT_FRAME::Show3D_Frame( wxCommandEvent& event ) { - EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame(); - - if( draw3DFrame ) - { - // Raising the window does not show the window on Windows if iconized. - // This should work on any platform. - if( draw3DFrame->IsIconized() ) - draw3DFrame->Iconize( false ); - - draw3DFrame->Raise(); - - // Raising the window does not set the focus on Linux. This should work on any platform. - if( wxWindow::FindFocus() != draw3DFrame ) - draw3DFrame->SetFocus(); - - return; - } - - draw3DFrame = new EDA_3D_VIEWER( &Kiway(), this, _( "3D Viewer" ) ); - draw3DFrame->SetDefaultFileName( GetBoard()->GetFileName() ); - draw3DFrame->Raise(); // Needed with some Window Managers - draw3DFrame->Show( true ); + bool forceRecreateIfNotOwner = true; + CreateAndShow3D_Frame( forceRecreateIfNotOwner ); } @@ -1087,10 +1067,7 @@ void PCB_EDIT_FRAME::OnModify( ) { PCB_BASE_FRAME::OnModify(); - EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame(); - - if( draw3DFrame ) - draw3DFrame->ReloadRequest(); + Update3DView(); m_ZoneFillsDirty = true; } diff --git a/qa/pcb_test_window/CMakeLists.txt b/qa/pcb_test_window/CMakeLists.txt index f3a83bc475..3bcc664dc4 100644 --- a/qa/pcb_test_window/CMakeLists.txt +++ b/qa/pcb_test_window/CMakeLists.txt @@ -82,6 +82,7 @@ target_link_libraries( test_window pnsrouter common pcbcommon + 3d-viewer bitmaps gal pcad2kicadpcb