centralized Esc key handling for closing the dialogs in wxDialogBase:

1. added wxDialogBase::OnCharHook() and removed this event handler from
   all the other ports
2. also removed ad hoc code doing the same thing in wxMSW (MSWProcessMessage()
   override in wxDialog) and wxGTK (in gtk_window_key_press_callback())
3. reimplemented EmulateButtonClickIfPresent() portably and also moved it
   to wxDialogBase from wxMSW wxDialog


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@40686 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2006-08-19 22:36:10 +00:00
parent 8f4931874c
commit 0be2741893
12 changed files with 82 additions and 169 deletions

View File

@@ -32,7 +32,6 @@ extern WXDLLEXPORT_DATA(const wxChar) wxDialogNameStr[];
class WXDLLEXPORT wxDialogBase : public wxTopLevelWindow
{
public:
enum
{
// all flags allowed in wxDialogBase::CreateButtonSizer()
@@ -72,6 +71,20 @@ public:
#endif // wxUSE_BUTTON
protected:
// emulate click of a button with the given id if it's present in the dialog
//
// return true if button was "clicked" or false if we don't have it
bool EmulateButtonClickIfPresent(int id);
// this function is used by OnCharHook() to decide whether the given key
// should close the dialog
//
// for most platforms the default implementation (which just checks for
// Esc) is sufficient, but Mac port also adds Cmd-. here and other ports
// could do something different if needed
virtual bool IsEscapeKey(const wxKeyEvent& event);
// The return code from modal dialog
int m_returnCode;
@@ -81,6 +94,10 @@ protected:
// The identifier for cancel button (usually wxID_CANCEL)
int m_escapeId;
private:
// handle Esc key presses
void OnCharHook(wxKeyEvent& event);
DECLARE_NO_COPY_CLASS(wxDialogBase)
DECLARE_EVENT_TABLE()
WX_DECLARE_CONTROL_CONTAINER();

View File

@@ -52,9 +52,6 @@ public:
void OnOK( wxCommandEvent &event );
void OnPaint( wxPaintEvent& event );
void OnCloseWindow( wxCloseEvent& event );
/*
void OnCharHook( wxKeyEvent& event );
*/
virtual bool Show( bool show = TRUE );
virtual int ShowModal();

View File

@@ -79,7 +79,6 @@ public:
// --------------
// event handlers
void OnCharHook(wxKeyEvent& event);
void OnCloseWindow(wxCloseEvent& event);
// Standard buttons

View File

@@ -17,8 +17,6 @@ class WXDLLEXPORT wxEventLoop;
// Dialog boxes
class WXDLLEXPORT wxDialog : public wxDialogBase
{
DECLARE_DYNAMIC_CLASS(wxDialog)
public:
wxDialog();
@@ -70,7 +68,6 @@ public:
// Responds to colour changes
void OnSysColourChanged(wxSysColourChangedEvent& event);
void OnCharHook(wxKeyEvent& event);
void OnCloseWindow(wxCloseEvent& event);
private:
@@ -97,7 +94,7 @@ protected:
private:
DECLARE_EVENT_TABLE()
DECLARE_DYNAMIC_CLASS(wxDialog)
};
#endif
// _WX_DIALOG_H_
#endif // _WX_DIALOG_H_

View File

@@ -86,7 +86,6 @@ public:
virtual void Raise();
// event handlers
void OnCharHook(wxKeyEvent& event);
void OnCloseWindow(wxCloseEvent& event);
// Standard buttons
@@ -123,9 +122,6 @@ public:
wxDEPRECATED( bool IsModalShowing() const );
#endif // WXWIN_COMPATIBILITY_2_6
// handle Escape here
virtual bool MSWProcessMessage(WXMSG* pMsg);
protected:
// find the window to use as parent for this dialog if none has been
// specified explicitly by the user
@@ -139,11 +135,6 @@ protected:
// end either modal or modeless dialog
void EndDialog(int rc);
// emulate click of a button with the given id if it's present in the dialog
//
// return true if button was "clicked" or false if we don't have it
bool EmulateButtonClickIfPresent(int id);
private:
wxWindow* m_oldFocus;
bool m_endModalCalled; // allow for closing within InitDialog

View File

@@ -68,7 +68,6 @@ public:
//
// Event handlers
//
void OnCharHook(wxKeyEvent& rEvent);
void OnCloseWindow(wxCloseEvent& rEvent);
//

View File

@@ -99,6 +99,7 @@ private:
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(wxDialogBase, wxTopLevelWindow)
EVT_CHAR_HOOK(wxDialogBase::OnCharHook)
WX_EVENT_TABLE_CONTROL_CONTAINER(wxDialogBase)
END_EVENT_TABLE()
@@ -417,3 +418,58 @@ wxStdDialogButtonSizer *wxDialogBase::CreateStdDialogButtonSizer( long flags )
}
#endif // wxUSE_BUTTON
// ----------------------------------------------------------------------------
// event handling stuff
// ----------------------------------------------------------------------------
bool wxDialogBase::EmulateButtonClickIfPresent(int id)
{
wxButton *btn = wxDynamicCast(FindWindow(id), wxButton);
if ( !btn || !btn->IsEnabled() || !btn->IsShown() )
return false;
wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, id);
event.SetEventObject(btn);
btn->GetEventHandler()->ProcessEvent(event);
return true;
}
bool wxDialogBase::IsEscapeKey(const wxKeyEvent& event)
{
// for most platforms, Esc key is used to close the dialogs
return event.GetKeyCode() == WXK_ESCAPE &&
event.GetModifiers() == wxMOD_NONE;
}
void wxDialogBase::OnCharHook(wxKeyEvent& event)
{
if ( event.GetKeyCode() == WXK_ESCAPE )
{
int idCancel = GetEscapeId();
switch ( idCancel )
{
case wxID_NONE:
// don't handle Esc specially at all
break;
case wxID_ANY:
// this value is special: it means translate Esc to wxID_CANCEL
// but if there is no such button, then fall back to wxID_OK
if ( EmulateButtonClickIfPresent(wxID_CANCEL) )
return;
idCancel = wxID_OK;
// fall through
default:
// translate Esc to button press for the button with given id
if ( EmulateButtonClickIfPresent(idCancel) )
return;
}
}
event.Skip();
}

View File

@@ -1152,43 +1152,6 @@ gtk_window_key_press_callback( GtkWidget *widget,
ret = win->GetParent()->GetEventHandler()->ProcessEvent( new_event );
}
// generate wxID_CANCEL if <esc> has been pressed (typically in dialogs)
if ( !ret &&
(gdk_event->keyval == GDK_Escape) )
{
// however only do it if we have a Cancel button in the dialog,
// otherwise the user code may get confused by the events from a
// nonexistent button and, worse, a wxButton might get button event
// from another button which is not really expected
wxWindow *winForCancel = win,
*btnCancel = NULL;
while ( winForCancel )
{
btnCancel = winForCancel->FindWindow(wxID_CANCEL);
if ( btnCancel )
{
// found a cancel button
break;
}
if ( winForCancel->IsTopLevel() )
{
// no need to look further
break;
}
// maybe our parent has a cancel button?
winForCancel = winForCancel->GetParent();
}
if ( btnCancel )
{
wxCommandEvent eventClick(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
eventClick.SetEventObject(btnCancel);
ret = btnCancel->GetEventHandler()->ProcessEvent(eventClick);
}
}
if (ret)
{
g_signal_stop_emission_by_name (widget, "key_press_event");

View File

@@ -34,8 +34,6 @@ BEGIN_EVENT_TABLE(wxDialog, wxDialogBase)
EVT_BUTTON(wxID_APPLY, wxDialog::OnApply)
EVT_BUTTON(wxID_CANCEL, wxDialog::OnCancel)
EVT_CHAR_HOOK(wxDialog::OnCharHook)
EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged)
EVT_CLOSE(wxDialog::OnCloseWindow)
@@ -102,24 +100,14 @@ wxDialog::~wxDialog()
Show(false);
}
// By default, pressing escape cancels the dialog; on mac command-stop does the same thing
void wxDialog::OnCharHook(wxKeyEvent& event)
// On mac command-stop does the same thing as Esc, let the base class know
// about it
bool wxDialog::IsEscapeKey(const wxKeyEvent& event)
{
if (( event.m_keyCode == WXK_ESCAPE ||
( event.m_keyCode == '.' && event.MetaDown() ) )
&& FindWindow(wxID_CANCEL) )
{
// Behaviour changed in 2.0: we'll send a Cancel message
// to the dialog instead of Close.
wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
cancelEvent.SetEventObject( this );
GetEventHandler()->ProcessEvent(cancelEvent);
if ( event.GetKeyCode() == '.' && event.GetModifiers() == wxMOD_CMD )
return true;
return;
}
// We didn't process this event.
event.Skip();
return wxDialogBase::IsEscapeKey(event);
}
bool wxDialog::IsModal() const

View File

@@ -75,7 +75,6 @@ BEGIN_EVENT_TABLE(wxDialog, wxTopLevelWindow)
EVT_BUTTON(wxID_OK, wxDialog::OnOK)
EVT_BUTTON(wxID_APPLY, wxDialog::OnApply)
EVT_BUTTON(wxID_CANCEL, wxDialog::OnCancel)
EVT_CHAR_HOOK(wxDialog::OnCharHook)
EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged)
EVT_CLOSE(wxDialog::OnCloseWindow)
END_EVENT_TABLE()
@@ -233,23 +232,6 @@ wxDialog::~wxDialog()
}
}
// By default, pressing escape cancels the dialog
void wxDialog::OnCharHook(wxKeyEvent& event)
{
if (event.m_keyCode == WXK_ESCAPE)
{
// Behaviour changed in 2.0: we'll send a Cancel message
// to the dialog instead of Close.
wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
cancelEvent.SetEventObject( this );
GetEventHandler()->ProcessEvent(cancelEvent);
return;
}
// We didn't process this event.
event.Skip();
}
void wxDialog::DoSetSize(int x, int y, int width, int height, int sizeFlags)
{
XtVaSetValues((Widget) m_mainWidget, XmNresizePolicy, XmRESIZE_ANY, NULL);

View File

@@ -389,17 +389,6 @@ void wxDialog::EndDialog(int rc)
// wxWin event handlers
// ----------------------------------------------------------------------------
bool wxDialog::EmulateButtonClickIfPresent(int id)
{
wxButton *btn = wxDynamicCast(FindWindow(id), wxButton);
if ( !btn || !btn->IsEnabled() || !btn->IsShown() )
return false;
btn->MSWCommand(BN_CLICKED, 0 /* unused */);
return true;
}
// Standard buttons
void wxDialog::OnOK(wxCommandEvent& WXUNUSED(event))
{
@@ -499,36 +488,6 @@ wxToolBar *wxDialog::OnCreateToolBar(long style,
// dialog Windows messages processing
// ---------------------------------------------------------------------------
bool wxDialog::MSWProcessMessage(WXMSG* pMsg)
{
const MSG * const msg = wx_reinterpret_cast(MSG *, pMsg);
if ( msg->message == WM_KEYDOWN && msg->wParam == VK_ESCAPE )
{
int idCancel = GetEscapeId();
switch ( idCancel )
{
case wxID_NONE:
// don't handle Esc specially at all
break;
case wxID_ANY:
// this value is special: it means translate Esc to wxID_CANCEL
// but if there is no such button, then fall back to wxID_OK
if ( EmulateButtonClickIfPresent(wxID_CANCEL) )
return true;
idCancel = wxID_OK;
// fall through
default:
// translate Esc to button press for the button with given id
if ( EmulateButtonClickIfPresent(idCancel) )
return true;
}
}
return wxDialogBase::MSWProcessMessage(pMsg);
}
WXLRESULT wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
{
WXLRESULT rc = 0;

View File

@@ -39,7 +39,6 @@ BEGIN_EVENT_TABLE(wxDialog, wxDialogBase)
EVT_BUTTON(wxID_OK, wxDialog::OnOK)
EVT_BUTTON(wxID_APPLY, wxDialog::OnApply)
EVT_BUTTON(wxID_CANCEL, wxDialog::OnCancel)
EVT_CHAR_HOOK(wxDialog::OnCharHook)
EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged)
EVT_CLOSE(wxDialog::OnCloseWindow)
@@ -163,40 +162,6 @@ wxDialog::~wxDialog()
Show(false);
} // end of wxDialog::~wxDialog
//
// By default, pressing escape cancels the dialog
//
void wxDialog::OnCharHook(
wxKeyEvent& rEvent
)
{
if (GetHWND())
{
if (rEvent.m_keyCode == WXK_ESCAPE)
{
//
// Behaviour changed in 2.0: we'll send a Cancel message
// to the dialog instead of Close.
//
wxCommandEvent vCancelEvent( wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
vCancelEvent.SetEventObject( this );
GetEventHandler()->ProcessEvent(vCancelEvent);
//
// Ensure that there is another message for this window so the
// ShowModal loop will exit and won't get stuck in GetMessage().
//
::WinPostMsg(GetHwnd(), WM_NULL, 0, 0);
return;
}
}
// We didn't process this event.
rEvent.Skip();
}
// ----------------------------------------------------------------------------
// showing the dialogs
// ----------------------------------------------------------------------------