]> git.saurik.com Git - wxWidgets.git/commitdiff
changed the handling of the default buttons to be more logical
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 11 May 2002 22:31:05 +0000 (22:31 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 11 May 2002 22:31:05 +0000 (22:31 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15516 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
include/wx/containr.h
include/wx/msw/button.h
include/wx/window.h
src/common/containr.cpp
src/msw/button.cpp
src/msw/window.cpp

index bdeb238c76bf85c97a437b4bf5514c7908d0a271..fc25ee8c8dbbe23ae5fd9f8b2a1ed400d618c1ca 100644 (file)
@@ -191,6 +191,7 @@ wxMSW:
 - Implemented wxMouseCaptureChangedEvent and made wxGenericDragImage check it
   has the capture before release it.
 - fixed bugs in multiple selection wxCheckListBox
+- default button handling is now closer to expected
 
 wxGTK:
 
index b74b2c2a8feb212a65ff5e0e353ae60392838936..d6df418e25ccd78aa09c7def9da5517b7a2cd7b6 100644 (file)
@@ -37,18 +37,29 @@ class WXDLLEXPORT wxWindowBase;
 
 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);
@@ -72,8 +83,13 @@ protected:
     // 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
@@ -94,6 +110,7 @@ public: \
     virtual void RemoveChild(wxWindowBase *child); \
     virtual wxWindow *GetDefaultItem() const; \
     virtual wxWindow *SetDefaultItem(wxWindow *child); \
+    virtual void SetTmpDefaultItem(wxWindow *win); \
 \
 protected: \
     wxControlContainer m_container
@@ -111,6 +128,11 @@ wxWindow *classname::SetDefaultItem(wxWindow *child) \
     return m_container.SetDefaultItem(child); \
 } \
  \
+void classname::SetTmpDefaultItem(wxWindow *child) \
+{ \
+    m_container.SetTmpDefaultItem(child); \
+} \
+ \
 wxWindow *classname::GetDefaultItem() const \
 { \
     return m_container.GetDefaultItem(); \
index 70f51f6fa5fede77054924b07612e1cfceaec609..77986f7e87c9bc207908fd18829f95849f479bc7 100644 (file)
@@ -69,6 +69,13 @@ protected:
     // send a notification event, return TRUE if processed
     bool SendClickEvent();
 
+    // default button handling
+    void SetTmpDefault();
+    void UnsetTmpDefault();
+
+    static void UpdateDefaultStyle(wxWindow *winDefault,
+                                   wxWindow *winOldDefault);
+
     // usually overridden base class virtuals
     virtual wxSize DoGetBestSize() const;
     virtual WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const;
index 94f9919e5da568833bd4c5ca9ab4e3072281ac8c..e048a847448cac1a82c922ca2512fdffa9339740 100644 (file)
@@ -400,6 +400,9 @@ public:
     virtual wxWindow *SetDefaultItem(wxWindow * WXUNUSED(child))
         { return NULL; }
 
+        // set this child as temporary default
+    virtual void SetTmpDefaultItem(wxWindow * WXUNUSED(win)) { }
+
     // parent/children relations
     // -------------------------
 
index 90a20eb8337dfb5a73a95daa1f7595dde1638ddb..624382ff2882ede90904a81d65fa7b13fc86657d 100644 (file)
@@ -45,6 +45,7 @@ wxControlContainer::wxControlContainer(wxWindow *winParent)
     m_winParent = winParent;
 
     m_winLastFocused =
+    m_winTmpDefault =
     m_winDefault = NULL;
 }
 
@@ -263,6 +264,9 @@ void wxControlContainer::HandleOnWindowDestroy(wxWindowBase *child)
 
     if ( child == m_winDefault )
         m_winDefault = NULL;
+
+    if ( child == m_winTmpDefault )
+        m_winTmpDefault = NULL;
 }
 
 // ----------------------------------------------------------------------------
index 2cafeca17ec76c63158349cf24ff0685423177c4..c00c3d11d04b10a6a517c367a76bb9c2f3f303d1 100644 (file)
@@ -180,36 +180,71 @@ wxSize wxButtonBase::GetDefaultSize()
 }
 
 // ----------------------------------------------------------------------------
-// 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
         {
@@ -219,12 +254,20 @@ void wxButton::SetDefault()
         }
     }
 
-    // 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();
+        }
     }
 }
 
@@ -266,13 +309,18 @@ bool wxButton::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
 
 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 )
     {
@@ -280,7 +328,7 @@ long wxButton::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
         // 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
index c633426aba86b02b789e1ae7e00df00431c32d75..b99b966f66475765a73c88daeb5798fcbd0bf56e 100644 (file)
@@ -1995,14 +1995,9 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
 
                                 return TRUE;
                             }
-                            else // no default button
+                            //else: no default button
 #endif // wxUSE_BUTTON
-                            {
-                                // no special function for enter and don't even
-                                // let IsDialogMessage() have it: it seems to
-                                // do something really strange with it
-                                return FALSE;
-                            }
+                            // treat Enter as TAB: pass to the next control
                         }
                     }
                     break;