Get rid of 5.0 dialog focus hacks.
It's time to fix the focus issues. This adds a new SetInitialFocus() routine to DIALOG_SHIM which will need to be called from a lot of dialogs. (cherry picked from commit 6d9647a)
This commit is contained in:
parent
a39fb03822
commit
0f78f97232
|
@ -58,7 +58,8 @@ DIALOG_SHIM::DIALOG_SHIM( wxWindow* aParent, wxWindowID id, const wxString& titl
|
||||||
const wxPoint& pos, const wxSize& size, long style, const wxString& name ) :
|
const wxPoint& pos, const wxSize& size, long style, const wxString& name ) :
|
||||||
wxDialog( aParent, id, title, pos, size, style, name ),
|
wxDialog( aParent, id, title, pos, size, style, name ),
|
||||||
KIWAY_HOLDER( 0 ),
|
KIWAY_HOLDER( 0 ),
|
||||||
m_fixupsRun( false ),
|
m_firstPaintEvent( true ),
|
||||||
|
m_initialFocusTarget( nullptr ),
|
||||||
m_qmodal_loop( 0 ),
|
m_qmodal_loop( 0 ),
|
||||||
m_qmodal_showing( false ),
|
m_qmodal_showing( false ),
|
||||||
m_qmodal_parent_disabler( 0 )
|
m_qmodal_parent_disabler( 0 )
|
||||||
|
@ -229,38 +230,29 @@ bool DIALOG_SHIM::Enable( bool enable )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Traverse all items in the dialog. If selectTextInTextCtrls, do a SelectAll()
|
#ifdef __WXMAC__
|
||||||
// in each so that tab followed by typing will replace the existing value.
|
// Recursive descent doing a SelectAll() in wxTextCtrls.
|
||||||
// Also collects the firstTextCtrl and the item with focus (if any).
|
// MacOS User Interface Guidelines state that when tabbing to a text control all its
|
||||||
static void recursiveDescent( wxWindowList& children, const bool selectTextInTextCtrls,
|
// text should be selected. Since wxWidgets fails to implement this, we do it here.
|
||||||
wxWindow* & firstTextCtrl, wxWindow* & windowWithFocus )
|
static void selectAllInTextCtrls( wxWindowList& children )
|
||||||
{
|
{
|
||||||
for( wxWindowList::iterator it = children.begin(); it != children.end(); ++it )
|
for( wxWindow* child : children )
|
||||||
{
|
{
|
||||||
wxWindow* child = *it;
|
|
||||||
|
|
||||||
if( child->HasFocus() )
|
|
||||||
windowWithFocus = child;
|
|
||||||
|
|
||||||
wxTextCtrl* childTextCtrl = dynamic_cast<wxTextCtrl*>( child );
|
wxTextCtrl* childTextCtrl = dynamic_cast<wxTextCtrl*>( child );
|
||||||
if( childTextCtrl )
|
if( childTextCtrl )
|
||||||
{
|
|
||||||
if( !firstTextCtrl && childTextCtrl->IsEnabled() && childTextCtrl->IsEditable() )
|
|
||||||
firstTextCtrl = childTextCtrl;
|
|
||||||
|
|
||||||
if( selectTextInTextCtrls )
|
|
||||||
{
|
{
|
||||||
wxTextEntry* asTextEntry = dynamic_cast<wxTextEntry*>( childTextCtrl );
|
wxTextEntry* asTextEntry = dynamic_cast<wxTextEntry*>( childTextCtrl );
|
||||||
|
|
||||||
// Respect an existing selection
|
// Respect an existing selection
|
||||||
if( asTextEntry->GetStringSelection().IsEmpty() )
|
if( asTextEntry->GetStringSelection().IsEmpty() )
|
||||||
asTextEntry->SelectAll();
|
asTextEntry->SelectAll();
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
selectAllInTextCtrls( child->GetChildren() );
|
||||||
recursiveDescent( child->GetChildren(), selectTextInTextCtrls, firstTextCtrl,
|
|
||||||
windowWithFocus );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef __WXMAC__
|
#ifdef __WXMAC__
|
||||||
static void fixOSXCancelButtonIssue( wxWindow *aWindow )
|
static void fixOSXCancelButtonIssue( wxWindow *aWindow )
|
||||||
|
@ -284,37 +276,19 @@ static void fixOSXCancelButtonIssue( wxWindow *aWindow )
|
||||||
|
|
||||||
void DIALOG_SHIM::OnPaint( wxPaintEvent &event )
|
void DIALOG_SHIM::OnPaint( wxPaintEvent &event )
|
||||||
{
|
{
|
||||||
if( !m_fixupsRun )
|
if( m_firstPaintEvent )
|
||||||
{
|
{
|
||||||
#if DLGSHIM_SELECT_ALL_IN_TEXT_CONTROLS
|
|
||||||
const bool selectAllInTextCtrls = true;
|
|
||||||
#else
|
|
||||||
const bool selectAllInTextCtrls = false;
|
|
||||||
#endif
|
|
||||||
wxWindow* firstTextCtrl = NULL;
|
|
||||||
wxWindow* windowWithFocus = NULL;
|
|
||||||
|
|
||||||
recursiveDescent( GetChildren(), selectAllInTextCtrls, firstTextCtrl,
|
|
||||||
windowWithFocus );
|
|
||||||
|
|
||||||
#if DLGSHIM_USE_SETFOCUS
|
|
||||||
// While it would be nice to honour any focus already set (which was
|
|
||||||
// recorded in windowWithFocus), the reality is that it's currently wrong
|
|
||||||
// far more often than it's right.
|
|
||||||
// So just focus on the first text control if we have one; otherwise the
|
|
||||||
// focus on the dialog itself, which will at least allow esc, return, etc.
|
|
||||||
// to function.
|
|
||||||
if( firstTextCtrl )
|
|
||||||
firstTextCtrl->SetFocus();
|
|
||||||
else
|
|
||||||
SetFocus();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __WXMAC__
|
#ifdef __WXMAC__
|
||||||
fixOSXCancelButtonIssue( this );
|
fixOSXCancelButtonIssue( this );
|
||||||
|
selectAllInTextCtrls( GetChildren() );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_fixupsRun = true;
|
if( m_initialFocusTarget )
|
||||||
|
m_initialFocusTarget->SetFocus();
|
||||||
|
else
|
||||||
|
SetFocus(); // Focus the dialog itself
|
||||||
|
|
||||||
|
m_firstPaintEvent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.Skip();
|
event.Skip();
|
||||||
|
|
|
@ -154,6 +154,8 @@ DIALOG_LABEL_EDITOR::DIALOG_LABEL_EDITOR( SCH_EDIT_FRAME* aParent, SCH_TEXT* aTe
|
||||||
m_textLabelMultiLine->Show( false );
|
m_textLabelMultiLine->Show( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetInitialFocus( m_activeTextCtrl );
|
||||||
|
|
||||||
if( m_CurrentText->Type() != SCH_TEXT_T )
|
if( m_CurrentText->Type() != SCH_TEXT_T )
|
||||||
( (wxTextValidator*) m_activeTextCtrl->GetValidator() )->SetCharExcludes( wxT( " /" ) );
|
( (wxTextValidator*) m_activeTextCtrl->GetValidator() )->SetCharExcludes( wxT( " /" ) );
|
||||||
|
|
||||||
|
@ -209,7 +211,6 @@ bool DIALOG_LABEL_EDITOR::TransferDataToWindow()
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_activeTextCtrl->SetValue( m_CurrentText->GetText() );
|
m_activeTextCtrl->SetValue( m_CurrentText->GetText() );
|
||||||
m_activeTextCtrl->SetFocus();
|
|
||||||
|
|
||||||
// Set text options:
|
// Set text options:
|
||||||
int orientation = mapOrientation( m_CurrentText->Type(), m_CurrentText->GetLabelSpinStyle() );
|
int orientation = mapOrientation( m_CurrentText->Type(), m_CurrentText->GetLabelSpinStyle() );
|
||||||
|
|
|
@ -611,7 +611,7 @@ DIALOG_FIELDS_EDITOR_GLOBAL::DIALOG_FIELDS_EDITOR_GLOBAL( SCH_EDIT_FRAME* parent
|
||||||
m_grid->AutoSizeColumns( false );
|
m_grid->AutoSizeColumns( false );
|
||||||
|
|
||||||
m_grid->SetGridCursor( 0, 1 );
|
m_grid->SetGridCursor( 0, 1 );
|
||||||
m_grid->SetFocus();
|
SetInitialFocus( m_grid );
|
||||||
|
|
||||||
m_sdbSizer1OK->SetDefault();
|
m_sdbSizer1OK->SetDefault();
|
||||||
|
|
||||||
|
|
|
@ -29,24 +29,7 @@
|
||||||
#include <hashtables.h>
|
#include <hashtables.h>
|
||||||
#include <kiway_player.h>
|
#include <kiway_player.h>
|
||||||
|
|
||||||
#ifdef __WXMAC__
|
|
||||||
/**
|
|
||||||
* MACOS requires this option to be set to 1 in order to set dialogs focus.
|
|
||||||
**/
|
|
||||||
#define DLGSHIM_USE_SETFOCUS 1
|
|
||||||
#else
|
|
||||||
#define DLGSHIM_USE_SETFOCUS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __WXMAC__
|
|
||||||
/**
|
|
||||||
* MACOS requires this option so that tabbing between text controls will
|
|
||||||
* arrive with the text selected.
|
|
||||||
**/
|
|
||||||
#define DLGSHIM_SELECT_ALL_IN_TEXT_CONTROLS 1
|
|
||||||
#else
|
|
||||||
#define DLGSHIM_SELECT_ALL_IN_TEXT_CONTROLS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class WDO_ENABLE_DISABLE;
|
class WDO_ENABLE_DISABLE;
|
||||||
class EVENT_LOOP;
|
class EVENT_LOOP;
|
||||||
|
@ -129,6 +112,15 @@ protected:
|
||||||
*/
|
*/
|
||||||
void FinishDialogSettings();
|
void FinishDialogSettings();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the window (usually a wxTextCtrl) that should be focused when the dialog is
|
||||||
|
* shown.
|
||||||
|
*/
|
||||||
|
void SetInitialFocus( wxWindow* aWindow )
|
||||||
|
{
|
||||||
|
m_initialFocusTarget = aWindow;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the dialog to the given dimensions in "dialog units". These are units equivalent
|
* Set the dialog to the given dimensions in "dialog units". These are units equivalent
|
||||||
* to 4* the average character width and 8* the average character height, allowing a dialog
|
* to 4* the average character width and 8* the average character height, allowing a dialog
|
||||||
|
@ -149,9 +141,14 @@ protected:
|
||||||
int VertPixelsFromDU( int y );
|
int VertPixelsFromDU( int y );
|
||||||
|
|
||||||
EDA_UNITS_T m_units; // userUnits for display and parsing
|
EDA_UNITS_T m_units; // userUnits for display and parsing
|
||||||
bool m_fixupsRun; // indicates various wxWidgets fixups have run
|
|
||||||
std::string m_hash_key; // alternate for class_map when classname re-used
|
std::string m_hash_key; // alternate for class_map when classname re-used
|
||||||
|
|
||||||
|
// On MacOS (at least) SetFocus() calls made in the constructor will fail because a
|
||||||
|
// window that isn't yet visible will return false to AcceptsFocus(). So we must delay
|
||||||
|
// the initial-focus SetFocus() call to the first paint event.
|
||||||
|
bool m_firstPaintEvent;
|
||||||
|
wxWindow* m_initialFocusTarget;
|
||||||
|
|
||||||
// variables for quasi-modal behavior support, only used by a few derivatives.
|
// variables for quasi-modal behavior support, only used by a few derivatives.
|
||||||
EVENT_LOOP* m_qmodal_loop; // points to nested event_loop, NULL means not qmodal and dismissed
|
EVENT_LOOP* m_qmodal_loop; // points to nested event_loop, NULL means not qmodal and dismissed
|
||||||
bool m_qmodal_showing;
|
bool m_qmodal_showing;
|
||||||
|
|
|
@ -82,6 +82,7 @@ DIALOG_SET_GRID::DIALOG_SET_GRID( PCB_BASE_FRAME* aParent, const wxArrayString&
|
||||||
m_comboBoxGrid2->Append( m_fast_grid_opts );
|
m_comboBoxGrid2->Append( m_fast_grid_opts );
|
||||||
|
|
||||||
m_sdbSizerOK->SetDefault(); // set OK button as default response to 'Enter' key
|
m_sdbSizerOK->SetDefault(); // set OK button as default response to 'Enter' key
|
||||||
|
SetInitialFocus( m_GridOriginXCtrl );
|
||||||
|
|
||||||
Layout();
|
Layout();
|
||||||
|
|
||||||
|
|
|
@ -275,6 +275,8 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParen
|
||||||
else
|
else
|
||||||
m_lockedCbox->Set3StateValue( wxCHK_UNCHECKED );
|
m_lockedCbox->Set3StateValue( wxCHK_UNCHECKED );
|
||||||
|
|
||||||
|
SetInitialFocus( m_tracks ? m_TrackStartXCtrl : m_ViaXCtrl );
|
||||||
|
|
||||||
m_StdButtonsOK->SetDefault();
|
m_StdButtonsOK->SetDefault();
|
||||||
|
|
||||||
// Now all widgets have the size fixed, call FinishDialogSettings
|
// Now all widgets have the size fixed, call FinishDialogSettings
|
||||||
|
|
Loading…
Reference in New Issue