class WXDLLEXPORT wxControlContainer
{
- DECLARE_NO_COPY_CLASS(wxControlContainer)
-
public:
// ctors and such
wxControlContainer(wxWindow *winParent = NULL);
void SetContainerWindow(wxWindow *winParent) { m_winParent = winParent; }
- // default item access
- wxWindow *GetDefaultItem() const { return m_winDefault; }
+ // default item access: we have a permanent default item which is the one
+ // set by the user code but we may also have a temporary default item which
+ // would be chosen if the user pressed "Enter" now but the default action
+ // reverts to the "permanent" default as soon as this temporary default
+ // item lsoes focus
+
+ // get the default item, temporary or permanent
+ wxWindow *GetDefaultItem() const
+ { return m_winTmpDefault ? m_winTmpDefault : m_winDefault; }
+
+ // set the permanent default item, return its old value
wxWindow *SetDefaultItem(wxWindow *win)
{ wxWindow *winOld = m_winDefault; m_winDefault = win; return winOld; }
+ // set a temporary default item, SetTmpDefaultItem(NULL) should be called
+ // soon after a call to SetTmpDefaultItem(window)
+ void SetTmpDefaultItem(wxWindow *win) { m_winTmpDefault = win; }
+
// the methods to be called from the window event handlers
void HandleOnNavigationKey(wxNavigationKeyEvent& event);
void HandleOnFocus(wxFocusEvent& event);
// the child which had the focus last time this panel was activated
wxWindow *m_winLastFocused;
- // a default window (e.g. a button) or NULL
+ // a default window (usually a button) or NULL
wxWindow *m_winDefault;
+
+ // a temporary override of m_winDefault, use the latter if NULL
+ wxWindow *m_winTmpDefault;
+
+ DECLARE_NO_COPY_CLASS(wxControlContainer)
};
// this function is for wxWindows internal use only
virtual void RemoveChild(wxWindowBase *child); \
virtual wxWindow *GetDefaultItem() const; \
virtual wxWindow *SetDefaultItem(wxWindow *child); \
+ virtual void SetTmpDefaultItem(wxWindow *win); \
\
protected: \
wxControlContainer m_container
return m_container.SetDefaultItem(child); \
} \
\
+void classname::SetTmpDefaultItem(wxWindow *child) \
+{ \
+ m_container.SetTmpDefaultItem(child); \
+} \
+ \
wxWindow *classname::GetDefaultItem() const \
{ \
return m_container.GetDefaultItem(); \
}
// ----------------------------------------------------------------------------
-// set this button as the default one in its panel
+// default button handling
// ----------------------------------------------------------------------------
+// set this button as the (permanently) default one in its panel
void wxButton::SetDefault()
{
wxWindow *parent = GetParent();
- wxButton *btnOldDefault;
- if ( parent )
- {
- wxWindow *winOldDefault = parent->SetDefaultItem(this);
- btnOldDefault = wxDynamicCast(winOldDefault, wxButton);
- ::SendMessage(GetWinHwnd(parent), DM_SETDEFID, m_windowId, 0L);
+ wxCHECK_RET( parent, _T("button without parent?") );
+
+ // set this one as the default button both for wxWindows and Windows
+ wxWindow *winOldDefault = parent->SetDefaultItem(this);
+ ::SendMessage(GetWinHwnd(parent), DM_SETDEFID, m_windowId, 0L);
+
+ UpdateDefaultStyle(this, winOldDefault);
+}
+
+void wxButton::SetTmpDefault()
+{
+ wxWindow *parent = GetParent();
+
+ wxCHECK_RET( parent, _T("button without parent?") );
+
+ wxWindow *winOldDefault = parent->GetDefaultItem();
+ parent->SetTmpDefaultItem(this);
+ if ( winOldDefault != this )
+ {
+ UpdateDefaultStyle(this, winOldDefault);
}
- else // is a button without parent really normal?
+ //else: no styles to update
+}
+
+void wxButton::UnsetTmpDefault()
+{
+ wxWindow *parent = GetParent();
+
+ wxCHECK_RET( parent, _T("button without parent?") );
+
+ parent->SetTmpDefaultItem(NULL);
+
+ wxWindow *winOldDefault = parent->GetDefaultItem();
+ if ( winOldDefault != this )
{
- btnOldDefault = NULL;
+ UpdateDefaultStyle(winOldDefault, this);
}
+ //else: we had been default before anyhow
+}
- if ( btnOldDefault && btnOldDefault != this )
+/* static */
+void
+wxButton::UpdateDefaultStyle(wxWindow *winDefault, wxWindow *winOldDefault)
+{
+ // clear the BS_DEFPUSHBUTTON for the old default button
+ wxButton *btnOldDefault = wxDynamicCast(winOldDefault, wxButton);
+ if ( btnOldDefault && btnOldDefault != winDefault )
{
// remove the BS_DEFPUSHBUTTON style from the other button
- long style = GetWindowLong(GetHwndOf(btnOldDefault), GWL_STYLE);
+ long style = ::GetWindowLong(GetHwndOf(btnOldDefault), GWL_STYLE);
// don't do it with the owner drawn buttons because it will reset
// BS_OWNERDRAW style bit too (BS_OWNERDRAW & BS_DEFPUSHBUTTON != 0)!
if ( (style & BS_OWNERDRAW) != BS_OWNERDRAW )
{
style &= ~BS_DEFPUSHBUTTON;
- SendMessage(GetHwndOf(btnOldDefault), BM_SETSTYLE, style, 1L);
+ ::SendMessage(GetHwndOf(btnOldDefault), BM_SETSTYLE, style, 1L);
}
else
{
}
}
- // set this button as the default
- long style = GetWindowLong(GetHwnd(), GWL_STYLE);
- if ( (style & BS_OWNERDRAW) != BS_OWNERDRAW )
+ // and set BS_DEFPUSHBUTTON for this button
+ wxButton *btnDefault = wxDynamicCast(winDefault, wxButton);
+ if ( btnDefault )
{
- style |= BS_DEFPUSHBUTTON;
- SendMessage(GetHwnd(), BM_SETSTYLE, style, 1L);
+ long style = ::GetWindowLong(GetHwndOf(btnDefault), GWL_STYLE);
+ if ( (style & BS_OWNERDRAW) != BS_OWNERDRAW )
+ {
+ style |= BS_DEFPUSHBUTTON;
+ ::SendMessage(GetHwndOf(btnDefault), BM_SETSTYLE, style, 1L);
+ }
+ else
+ {
+ btnDefault->Refresh();
+ }
}
}
long wxButton::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
{
- // when we receive focus, we want to become the default button in our
- // parent panel
+ // when we receive focus, we want to temporary become the default button in
+ // our parent panel so that pressing "Enter" would activate us -- and when
+ // losing it we should restore the previous default button as well
if ( nMsg == WM_SETFOCUS )
{
- SetDefault();
+ SetTmpDefault();
- // let the default processign take place too
+ // let the default processing take place too
+ }
+ else if ( nMsg == WM_KILLFOCUS )
+ {
+ UnsetTmpDefault();
}
else if ( nMsg == WM_LBUTTONDBLCLK )
{
// appearance - without this, it won't do it
(void)wxControl::MSWWindowProc(WM_LBUTTONDOWN, wParam, lParam);
- // and conitnue with processing the message normally as well
+ // and continue with processing the message normally as well
}
// let the base class do all real processing