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 ) :
|
||||
wxDialog( aParent, id, title, pos, size, style, name ),
|
||||
KIWAY_HOLDER( 0 ),
|
||||
m_fixupsRun( false ),
|
||||
m_firstPaintEvent( true ),
|
||||
m_initialFocusTarget( nullptr ),
|
||||
m_qmodal_loop( 0 ),
|
||||
m_qmodal_showing( false ),
|
||||
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()
|
||||
// in each so that tab followed by typing will replace the existing value.
|
||||
// Also collects the firstTextCtrl and the item with focus (if any).
|
||||
static void recursiveDescent( wxWindowList& children, const bool selectTextInTextCtrls,
|
||||
wxWindow* & firstTextCtrl, wxWindow* & windowWithFocus )
|
||||
#ifdef __WXMAC__
|
||||
// Recursive descent doing a SelectAll() in wxTextCtrls.
|
||||
// MacOS User Interface Guidelines state that when tabbing to a text control all its
|
||||
// text should be selected. Since wxWidgets fails to implement this, we do it here.
|
||||
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 );
|
||||
if( childTextCtrl )
|
||||
{
|
||||
if( !firstTextCtrl && childTextCtrl->IsEnabled() && childTextCtrl->IsEditable() )
|
||||
firstTextCtrl = childTextCtrl;
|
||||
wxTextEntry* asTextEntry = dynamic_cast<wxTextEntry*>( childTextCtrl );
|
||||
|
||||
if( selectTextInTextCtrls )
|
||||
{
|
||||
wxTextEntry* asTextEntry = dynamic_cast<wxTextEntry*>( childTextCtrl );
|
||||
// Respect an existing selection
|
||||
if( asTextEntry->GetStringSelection().IsEmpty() )
|
||||
asTextEntry->SelectAll();
|
||||
}
|
||||
// Respect an existing selection
|
||||
if( asTextEntry->GetStringSelection().IsEmpty() )
|
||||
asTextEntry->SelectAll();
|
||||
}
|
||||
|
||||
recursiveDescent( child->GetChildren(), selectTextInTextCtrls, firstTextCtrl,
|
||||
windowWithFocus );
|
||||
else
|
||||
selectAllInTextCtrls( child->GetChildren() );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __WXMAC__
|
||||
static void fixOSXCancelButtonIssue( wxWindow *aWindow )
|
||||
|
@ -284,37 +276,19 @@ static void fixOSXCancelButtonIssue( wxWindow *aWindow )
|
|||
|
||||
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 );
|
||||
selectAllInTextCtrls( GetChildren() );
|
||||
#endif
|
||||
|
||||
m_fixupsRun = true;
|
||||
if( m_initialFocusTarget )
|
||||
m_initialFocusTarget->SetFocus();
|
||||
else
|
||||
SetFocus(); // Focus the dialog itself
|
||||
|
||||
m_firstPaintEvent = false;
|
||||
}
|
||||
|
||||
event.Skip();
|
||||
|
|
|
@ -154,6 +154,8 @@ DIALOG_LABEL_EDITOR::DIALOG_LABEL_EDITOR( SCH_EDIT_FRAME* aParent, SCH_TEXT* aTe
|
|||
m_textLabelMultiLine->Show( false );
|
||||
}
|
||||
|
||||
SetInitialFocus( m_activeTextCtrl );
|
||||
|
||||
if( m_CurrentText->Type() != SCH_TEXT_T )
|
||||
( (wxTextValidator*) m_activeTextCtrl->GetValidator() )->SetCharExcludes( wxT( " /" ) );
|
||||
|
||||
|
@ -209,7 +211,6 @@ bool DIALOG_LABEL_EDITOR::TransferDataToWindow()
|
|||
return false;
|
||||
|
||||
m_activeTextCtrl->SetValue( m_CurrentText->GetText() );
|
||||
m_activeTextCtrl->SetFocus();
|
||||
|
||||
// Set text options:
|
||||
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->SetGridCursor( 0, 1 );
|
||||
m_grid->SetFocus();
|
||||
SetInitialFocus( m_grid );
|
||||
|
||||
m_sdbSizer1OK->SetDefault();
|
||||
|
||||
|
|
|
@ -29,24 +29,7 @@
|
|||
#include <hashtables.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 EVENT_LOOP;
|
||||
|
@ -129,6 +112,15 @@ protected:
|
|||
*/
|
||||
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
|
||||
* to 4* the average character width and 8* the average character height, allowing a dialog
|
||||
|
@ -149,9 +141,14 @@ protected:
|
|||
int VertPixelsFromDU( int y );
|
||||
|
||||
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
|
||||
|
||||
// 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.
|
||||
EVENT_LOOP* m_qmodal_loop; // points to nested event_loop, NULL means not qmodal and dismissed
|
||||
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_sdbSizerOK->SetDefault(); // set OK button as default response to 'Enter' key
|
||||
SetInitialFocus( m_GridOriginXCtrl );
|
||||
|
||||
Layout();
|
||||
|
||||
|
|
|
@ -275,6 +275,8 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParen
|
|||
else
|
||||
m_lockedCbox->Set3StateValue( wxCHK_UNCHECKED );
|
||||
|
||||
SetInitialFocus( m_tracks ? m_TrackStartXCtrl : m_ViaXCtrl );
|
||||
|
||||
m_StdButtonsOK->SetDefault();
|
||||
|
||||
// Now all widgets have the size fixed, call FinishDialogSettings
|
||||
|
|
Loading…
Reference in New Issue