diff --git a/common/kiway.cpp b/common/kiway.cpp index a5ca94f46a..d7a870fc03 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -48,10 +48,19 @@ KIWAY::KIWAY( PGM_BASE* aProgram, int aCtlBits, wxFrame* aTop ): { SetTop( aTop ); // hook player_destroy_handler() into aTop. - memset( m_player, 0, sizeof( m_player ) ); + + // Prepare the room to store the frame names, once they will be created + // with FRAME_T type as index in this table. + // (note this is a list of frame names, but a non empty entry + // does not mean the frame still exists. It means only the frame was created + // at least once. It can be destroyed after. These entries are not cleared. + // the purpose is just to allow a call to wxWindow::FindWindowByName(), from + // a FRAME_T frame type + m_playerFrameName.Add( wxEmptyString, KIWAY_PLAYER_COUNT ); } +#if 0 // Any event types derived from wxCommandEvt, like wxWindowDestroyEvent, are // propogated upwards to parent windows if not handled below. Therefore the // m_top window should receive all wxWindowDestroyEvents originating from @@ -60,26 +69,14 @@ KIWAY::KIWAY( PGM_BASE* aProgram, int aCtlBits, wxFrame* aTop ): void KIWAY::player_destroy_handler( wxWindowDestroyEvent& event ) { - wxWindow* w = event.GetWindow(); - - for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i ) - { - // if destroying one of our flock, then mark it as deceased. - if( (wxWindow*) m_player[i] == w ) - { - DBG(printf( "%s: m_player[%u] destroyed: %s\n", - __func__, i, TO_UTF8( m_player[i]->GetName() ) );) - - m_player[i] = 0; - } - } - + // Currently : do nothing event.Skip(); // skip to who, the wxApp? I'm the top window. } - +#endif void KIWAY::SetTop( wxFrame* aTop ) { +#if 0 if( m_top ) { m_top->Disconnect( wxEVT_DESTROY, wxWindowDestroyEventHandler( KIWAY::player_destroy_handler ), NULL, this ); @@ -89,6 +86,7 @@ void KIWAY::SetTop( wxFrame* aTop ) { aTop->Connect( wxEVT_DESTROY, wxWindowDestroyEventHandler( KIWAY::player_destroy_handler ), NULL, this ); } +#endif m_top = aTop; } @@ -271,14 +269,15 @@ KIWAY::FACE_T KIWAY::KifaceType( FRAME_T aFrameType ) KIWAY_PLAYER* KIWAY::GetPlayerFrame( FRAME_T aFrameType ) { - if( unsigned( aFrameType ) >= KIWAY_PLAYER_COUNT ) + if( m_playerFrameName[aFrameType].IsEmpty() ) return NULL; - return m_player[aFrameType]; + return static_cast( wxWindow::FindWindowByName( m_playerFrameName[aFrameType] ) ); } -KIWAY_PLAYER* KIWAY::Player( FRAME_T aFrameType, bool doCreate ) + +KIWAY_PLAYER* KIWAY::Player( FRAME_T aFrameType, bool doCreate, KIWAY_PLAYER* aParent ) { // Since this will be called from python, cannot assume that code will // not pass a bad aFrameType. @@ -308,14 +307,16 @@ KIWAY_PLAYER* KIWAY::Player( FRAME_T aFrameType, bool doCreate ) if( kiface ) { frame = (KIWAY_PLAYER*) kiface->CreateWindow( - m_top, + aParent, // Parent window of frame, NULL in non modal mode aFrameType, this, - m_ctl // questionable need, these same flags where passed to the KIFACE::OnKifaceStart() + m_ctl // questionable need, these same flags where passed to the KIFACE::OnKifaceStart() ); wxASSERT( frame ); - return m_player[aFrameType] = frame; + m_playerFrameName[aFrameType] = frame->GetName(); + + return frame; } } @@ -342,10 +343,7 @@ bool KIWAY::PlayerClose( FRAME_T aFrameType, bool doForce ) return true; if( frame->Close( doForce ) ) - { - m_player[aFrameType] = 0; return true; - } return false; } diff --git a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp index 2e974e18d2..96adbe614a 100644 --- a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp +++ b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp @@ -532,7 +532,7 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::showButtonHandler( wxCommandEvent& even // pick a footprint using the footprint picker. wxString fpid; - KIWAY_PLAYER* frame = Kiway().Player( FRAME_PCB_MODULE_VIEWER_MODAL, true ); + KIWAY_PLAYER* frame = Kiway().Player( FRAME_PCB_MODULE_VIEWER_MODAL, true, m_parent ); if( frame->ShowModal( &fpid, this ) ) { diff --git a/eeschema/getpart.cpp b/eeschema/getpart.cpp index 1fc44cd073..6e119ae5a4 100644 --- a/eeschema/getpart.cpp +++ b/eeschema/getpart.cpp @@ -62,7 +62,7 @@ wxString SCH_BASE_FRAME::SelectComponentFromLibBrowser( const SCHLIB_FILTER* aFi if( viewlibFrame ) viewlibFrame->Destroy(); - viewlibFrame = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER_MODAL, true ); + viewlibFrame = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER_MODAL, true, this ); if( aFilter ) viewlibFrame->SetFilter( aFilter ); diff --git a/eeschema/viewlib_frame.cpp b/eeschema/viewlib_frame.cpp index 6eddf45f81..36af402e52 100644 --- a/eeschema/viewlib_frame.cpp +++ b/eeschema/viewlib_frame.cpp @@ -77,20 +77,22 @@ END_EVENT_TABLE() /* Note: - * LIB_VIEW_FRAME can be build in "modal mode", or as a usual frame. + * LIB_VIEW_FRAME can be created in "modal mode", or as a usual frame. * In modal mode: * a tool to export the selected symbol is shown in the toolbar - * the style is wxSTAY_ON_TOP on Windows and wxFRAME_FLOAT_ON_PARENT on unix - * reason: - * the parent is usually the kicad window manager (not easy to change) - * On windows, when the frame with stype wxFRAME_FLOAT_ON_PARENT is displayed - * its parent frame is brought to the foreground, on the top of the calling frame. - * and stays displayed when closing the LIB_VIEW_FRAME frame. - * this issue does not happen on unix. - * - * So we use wxSTAY_ON_TOP on Windows, and wxFRAME_FLOAT_ON_PARENT on unix - * to simulate a dialog called by ShowModal. + * the style is wxFRAME_FLOAT_ON_PARENT + * Note: + * On windows, when the frame with type wxFRAME_FLOAT_ON_PARENT is displayed + * its parent frame is sometimes brought to the foreground when closing the + * LIB_VIEW_FRAME frame. + * If it still happens, it could be better to use wxSTAY_ON_TOP + * instead of wxFRAME_FLOAT_ON_PARENT */ +#ifdef __WINDOWS__ +#define MODAL_MODE_EXTRASTYLE wxFRAME_FLOAT_ON_PARENT // could be wxSTAY_ON_TOP if issues +#else +#define MODAL_MODE_EXTRASTYLE wxFRAME_FLOAT_ON_PARENT +#endif #define LIB_VIEW_FRAME_NAME wxT( "ViewlibFrame" ) #define LIB_VIEW_FRAME_NAME_MODAL wxT( "ViewlibFrameModal" ) @@ -99,18 +101,15 @@ LIB_VIEW_FRAME::LIB_VIEW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame PART_LIB* aLibrary ) : SCH_BASE_FRAME( aKiway, aParent, aFrameType, _( "Library Browser" ), wxDefaultPosition, wxDefaultSize, - aFrameType==FRAME_SCH_VIEWER_MODAL ? -#ifdef __WINDOWS__ - KICAD_DEFAULT_DRAWFRAME_STYLE | wxSTAY_ON_TOP -#else - aParent ? KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT + aFrameType == FRAME_SCH_VIEWER_MODAL ? + aParent ? KICAD_DEFAULT_DRAWFRAME_STYLE | MODAL_MODE_EXTRASTYLE : KICAD_DEFAULT_DRAWFRAME_STYLE | wxSTAY_ON_TOP -#endif : KICAD_DEFAULT_DRAWFRAME_STYLE, aFrameType == FRAME_SCH_VIEWER_MODAL ? LIB_VIEW_FRAME_NAME_MODAL : LIB_VIEW_FRAME_NAME ) { - wxASSERT( aFrameType == FRAME_SCH_VIEWER || aFrameType == FRAME_SCH_VIEWER_MODAL ); + wxASSERT( aFrameType == FRAME_SCH_VIEWER || + aFrameType == FRAME_SCH_VIEWER_MODAL ); if( aFrameType == FRAME_SCH_VIEWER_MODAL ) SetModal( true ); diff --git a/include/kiway.h b/include/kiway.h index 347c0bb92e..10340ac25d 100644 --- a/include/kiway.h +++ b/include/kiway.h @@ -298,11 +298,13 @@ public: * @param aFrameType is from enum #FRAME_T. * @param doCreate when true asks that the player be created if it is not * already created, false means do not create and maybe return NULL. + * @param aParent is a parent for modal KIWAY_PLAYER frames, otherwise NULL + * used only when doCreate = true * * @return KIWAY_PLAYER* - a valid opened KIWAY_PLAYER or NULL if there * is something wrong or doCreate was false and the player has yet to be created. */ - VTBL_ENTRY KIWAY_PLAYER* Player( FRAME_T aFrameType, bool doCreate = true ); + VTBL_ENTRY KIWAY_PLAYER* Player( FRAME_T aFrameType, bool doCreate = true, KIWAY_PLAYER* aParent = NULL ); /** * Function PlayerClose @@ -369,8 +371,10 @@ private: /// Get the full path & name of the DSO holding the requested FACE_T. static const wxString dso_full_path( FACE_T aFaceId ); +#if 0 /// hooked into m_top in SetTop(), marks child frame as closed. void player_destroy_handler( wxWindowDestroyEvent& event ); +#endif bool set_kiface( FACE_T aFaceType, KIFACE* aKiface ) { @@ -393,10 +397,17 @@ private: PGM_BASE* m_program; int m_ctl; + wxFrame* m_top; // Usually m_top is the Project manager - KIWAY_PLAYER* m_player[KIWAY_PLAYER_COUNT]; // from frame_type.h + // a string array ( size KIWAY_PLAYER_COUNT ) to Store the frame name + // of PLAYER frames which were run. + // A non empty name means only a PLAYER was run at least one time. + // It can be closed. Call : + // wxWindow::FindWindowByName( m_playerFrameName[aFrameType] ) + // to know if still exists (or GetPlayerFrame( FRAME_T aFrameType ) + wxArrayString m_playerFrameName; PROJECT m_project; // do not assume this is here, use Prj(). }; diff --git a/pcbnew/footprint_wizard_frame.cpp b/pcbnew/footprint_wizard_frame.cpp index 47bb737535..adc54b5ab2 100644 --- a/pcbnew/footprint_wizard_frame.cpp +++ b/pcbnew/footprint_wizard_frame.cpp @@ -88,16 +88,26 @@ int FOOTPRINT_WIZARD_FRAME::m_columnPrmUnit = 2; #define FOOTPRINT_WIZARD_FRAME_NAME wxT( "FootprintWizard" ) +/* Note: our FOOTPRINT_WIZARD_FRAME is always modal. + * Note: + * On windows, when the frame with type wxFRAME_FLOAT_ON_PARENT is displayed + * its parent frame is sometimes brought to the foreground when closing the + * LIB_VIEW_FRAME frame. + * If it still happens, it could be better to use wxSTAY_ON_TOP + * instead of wxFRAME_FLOAT_ON_PARENT + */ +#ifdef __WINDOWS__ +#define MODAL_MODE_EXTRASTYLE wxFRAME_FLOAT_ON_PARENT // could be wxSTAY_ON_TOP if issues +#else +#define MODAL_MODE_EXTRASTYLE wxFRAME_FLOAT_ON_PARENT +#endif + FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType ) : PCB_BASE_FRAME( aKiway, aParent, aFrameType, _( "Footprint Wizard" ), wxDefaultPosition, wxDefaultSize, -#ifdef __WINDOWS__ - KICAD_DEFAULT_DRAWFRAME_STYLE | wxSTAY_ON_TOP, -#else - aParent ? KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT + aParent ? KICAD_DEFAULT_DRAWFRAME_STYLE | MODAL_MODE_EXTRASTYLE : KICAD_DEFAULT_DRAWFRAME_STYLE | wxSTAY_ON_TOP, -#endif FOOTPRINT_WIZARD_FRAME_NAME ) { wxASSERT( aFrameType == FRAME_PCB_FOOTPRINT_WIZARD_MODAL ); diff --git a/pcbnew/loadcmp.cpp b/pcbnew/loadcmp.cpp index f72243a27c..7527b0c684 100644 --- a/pcbnew/loadcmp.cpp +++ b/pcbnew/loadcmp.cpp @@ -136,17 +136,17 @@ wxString PCB_BASE_FRAME::SelectFootprintFromLibBrowser() { // Close the current non-modal Lib browser if opened, and open a new one, in "modal" mode: FOOTPRINT_VIEWER_FRAME* viewer; - viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_PCB_MODULE_VIEWER, false ); if( viewer ) viewer->Destroy(); + SetFocus(); + // Creates the modal Lib browser: - viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_PCB_MODULE_VIEWER_MODAL, true ); + viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_PCB_MODULE_VIEWER_MODAL, true, this ); wxString fpid; - int ret = viewer->ShowModal( &fpid, this ); (void) ret; // make static analyser quiet diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp index c51e171f4c..faa471a374 100644 --- a/pcbnew/modedit.cpp +++ b/pcbnew/modedit.cpp @@ -344,7 +344,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) } FOOTPRINT_WIZARD_FRAME* wizard = (FOOTPRINT_WIZARD_FRAME*) Kiway().Player( - FRAME_PCB_FOOTPRINT_WIZARD_MODAL, true ); + FRAME_PCB_FOOTPRINT_WIZARD_MODAL, true, this ); if( wizard->ShowModal( NULL, this ) ) { diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp index ef2a97e9dc..e54b695563 100644 --- a/pcbnew/modview_frame.cpp +++ b/pcbnew/modview_frame.cpp @@ -100,18 +100,19 @@ END_EVENT_TABLE() * FOOTPRINT_VIEWER_FRAME can be created in "modal mode", or as a usual frame. * In modal mode: * a tool to export the selected footprint is shown in the toolbar - * the style is wxSTAY_ON_TOP on Windows and wxFRAME_FLOAT_ON_PARENT on unix - * Reason: - * the parent is usually the kicad window manager (not easy to change) - * On windows, when the frame with stype wxFRAME_FLOAT_ON_PARENT is displayed - * its parent frame is brought to the foreground, on the top of the calling frame. - * and stays displayed when closing the FOOTPRINT_VIEWER_FRAME frame. - * this issue does not happen on unix - * - * So we use wxSTAY_ON_TOP on Windows, and wxFRAME_FLOAT_ON_PARENT on unix - * to force FOOTPRINT_VIEWER_FRAME to stay on parent when it is Modal. + * the style is wxFRAME_FLOAT_ON_PARENT + * Note: + * On windows, when the frame with type wxFRAME_FLOAT_ON_PARENT is displayed + * its parent frame is sometimes brought to the foreground when closing the + * LIB_VIEW_FRAME frame. + * If it still happens, it could be better to use wxSTAY_ON_TOP + * instead of wxFRAME_FLOAT_ON_PARENT */ - +#ifdef __WINDOWS__ +#define MODAL_MODE_EXTRASTYLE wxFRAME_FLOAT_ON_PARENT // could be wxSTAY_ON_TOP if issues +#else +#define MODAL_MODE_EXTRASTYLE wxFRAME_FLOAT_ON_PARENT +#endif #define FOOTPRINT_VIEWER_FRAME_NAME wxT( "ModViewFrame" ) #define FOOTPRINT_VIEWER_FRAME_NAME_MODAL wxT( "ModViewFrameModal" ) @@ -121,20 +122,16 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent PCB_BASE_FRAME( aKiway, aParent, aFrameType, _( "Footprint Library Browser" ), wxDefaultPosition, wxDefaultSize, aFrameType == FRAME_PCB_MODULE_VIEWER_MODAL ? -#ifdef __WINDOWS__ - KICAD_DEFAULT_DRAWFRAME_STYLE | wxSTAY_ON_TOP -#else aParent ? - KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT + KICAD_DEFAULT_DRAWFRAME_STYLE | MODAL_MODE_EXTRASTYLE : KICAD_DEFAULT_DRAWFRAME_STYLE | wxSTAY_ON_TOP -#endif : KICAD_DEFAULT_DRAWFRAME_STYLE, aFrameType == FRAME_PCB_MODULE_VIEWER_MODAL ? FOOTPRINT_VIEWER_FRAME_NAME_MODAL : FOOTPRINT_VIEWER_FRAME_NAME ) { - wxASSERT( aFrameType==FRAME_PCB_MODULE_VIEWER || - aFrameType==FRAME_PCB_MODULE_VIEWER_MODAL ); + wxASSERT( aFrameType == FRAME_PCB_MODULE_VIEWER_MODAL || + aFrameType == FRAME_PCB_MODULE_VIEWER ); if( aFrameType == FRAME_PCB_MODULE_VIEWER_MODAL ) SetModal( true ); @@ -305,6 +302,11 @@ void FOOTPRINT_VIEWER_FRAME::OnCloseWindow( wxCloseEvent& Event ) { DBG(printf( "%s:\n", __func__ );) + // A workaround to avoid flicker, in modal mode when modview frame is destroyed, + // when the aui toolbar is not docked (i.e. shown in a miniframe) + // (usefull on windows only) + m_mainToolBar->SetFocus(); + if( IsGalCanvasActive() ) GetGalCanvas()->StopDrawing();