Change the way main editor frames are managed by Kicad: before this change, they had the Kicad manager frame as parent frame, and it creates a few issues:
- When the Kicad manager is iconized, all other child frames are iconized (normal wxWidgets behavior) - For viewer frames in modal mode, there is a more annoying issue: they have the wxFLOAT_ON_PARENT frame style on unix, and wxSTAY_ON_TOP on Windows. wxFLOAT_ON_PARENT frame style is incorrect (although on most WM it works) because the parent frame (Kicad manager Frame) is not the caller. It is usually a main editor frame. It does not work on Windows (wx STAY_ON_TOP is used). * Now each editor frame has a null parent. Therefore iconizing the Kicad manager frame does not iconize other frames. * Viewer frames have null parent in normal mode and the caller parent in modal mode (therefore wxFLOAT_ON_PARENT frame style is always and correctly used) * References to opened/closed main frames are no more managed by the (complicated) kicad code. Instead of, a non critical and more easy to understand code just uses FindWindowByName to know if a main window exists or not. These changes do not fix all issues about Kicad frames brought to the foreground or the background, but it fixes a few issues, and AFAIK do not add other issues.
This commit is contained in:
parent
2d4845ddae
commit
99d18faca9
|
@ -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<KIWAY_PLAYER*>( 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;
|
||||
}
|
||||
|
|
|
@ -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 ) )
|
||||
{
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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().
|
||||
};
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 ) )
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue