]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/compositewin.h
support SDK < 10.6, fixes #14902
[wxWidgets.git] / include / wx / compositewin.h
index 9d12ee6fad946abca97dfc0184af1b4c2643e0be..567cd746bc86c14e39bbfeb4d6259e6429864609 100644 (file)
@@ -3,7 +3,7 @@
 // Purpose:     wxCompositeWindow<> declaration
 // Author:      Vadim Zeitlin
 // Created:     2011-01-02
 // Purpose:     wxCompositeWindow<> declaration
 // Author:      Vadim Zeitlin
 // Created:     2011-01-02
-// RCS-ID:      $Id: wxhead.h,v 1.12 2010-04-22 12:44:51 zeitlin Exp $
+// RCS-ID:      $Id$
 // Copyright:   (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
 // Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 // Copyright:   (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
 // Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
@@ -12,6 +12,9 @@
 #define _WX_COMPOSITEWIN_H_
 
 #include "wx/window.h"
 #define _WX_COMPOSITEWIN_H_
 
 #include "wx/window.h"
+#include "wx/containr.h"
+
+class WXDLLIMPEXP_FWD_CORE wxToolTip;
 
 // NB: This is an experimental and, as for now, undocumented class used only by
 //     wxWidgets itself internally. Don't use it in your code until its API is
 
 // NB: This is an experimental and, as for now, undocumented class used only by
 //     wxWidgets itself internally. Don't use it in your code until its API is
@@ -32,7 +35,25 @@ public:
     typedef W BaseWindowClass;
 
     // Default ctor doesn't do anything.
     typedef W BaseWindowClass;
 
     // Default ctor doesn't do anything.
-    wxCompositeWindow() { }
+    wxCompositeWindow()
+    {
+        this->Connect
+              (
+                  wxEVT_CREATE,
+                  wxWindowCreateEventHandler(wxCompositeWindow::OnWindowCreate)
+              );
+
+    }
+
+#ifndef __VISUALC6__
+    // FIXME-VC6: This compiler can't compile DoSetForAllParts() template function,
+    // it can't determine whether the deduced type should be "T" or "const T&". And
+    // without this function wxCompositeWindow is pretty useless so simply disable
+    // this code for it, this does mean that setting colours/fonts/... for
+    // composite controls won't work in the library compiled with it but so far
+    // this only affects the generic wxDatePickerCtrl which is not used by default
+    // under MSW anyhow so it doesn't seem to be worth it to spend time and uglify
+    // the code to fix it.
 
     // Override all wxWindow methods which must be forwarded to the composite
     // window parts.
 
     // Override all wxWindow methods which must be forwarded to the composite
     // window parts.
@@ -49,7 +70,7 @@ public:
         if ( !BaseWindowClass::SetForegroundColour(colour) )
             return false;
 
         if ( !BaseWindowClass::SetForegroundColour(colour) )
             return false;
 
-        DoSetForAllParts(&wxWindowBase::SetForegroundColour, colour);
+        SetForAllParts(&wxWindowBase::SetForegroundColour, colour);
 
         return true;
     }
 
         return true;
     }
@@ -59,7 +80,7 @@ public:
         if ( !BaseWindowClass::SetBackgroundColour(colour) )
             return false;
 
         if ( !BaseWindowClass::SetBackgroundColour(colour) )
             return false;
 
-        DoSetForAllParts(&wxWindowBase::SetBackgroundColour, colour);
+        SetForAllParts(&wxWindowBase::SetBackgroundColour, colour);
 
         return true;
     }
 
         return true;
     }
@@ -69,7 +90,7 @@ public:
         if ( !BaseWindowClass::SetFont(font) )
             return false;
 
         if ( !BaseWindowClass::SetFont(font) )
             return false;
 
-        DoSetForAllParts(&wxWindowBase::SetFont, font);
+        SetForAllParts(&wxWindowBase::SetFont, font);
 
         return true;
     }
 
         return true;
     }
@@ -79,18 +100,112 @@ public:
         if ( !BaseWindowClass::SetCursor(cursor) )
             return false;
 
         if ( !BaseWindowClass::SetCursor(cursor) )
             return false;
 
-        DoSetForAllParts(&wxWindowBase::SetCursor, cursor);
+        SetForAllParts(&wxWindowBase::SetCursor, cursor);
 
         return true;
     }
 
 
         return true;
     }
 
+#if wxUSE_TOOLTIPS
+    virtual void DoSetToolTip(wxToolTip *tip)
+    {
+        BaseWindowClass::DoSetToolTip(tip);
+
+        SetForAllParts(&wxWindowBase::CopyToolTip, tip);
+    }
+#endif // wxUSE_TOOLTIPS
+
+#endif // !__VISUALC6__
+
+    virtual void SetFocus()
+    {
+        wxSetFocusToChild(this, NULL);
+    }
+
 private:
     // Must be implemented by the derived class to return all children to which
     // the public methods we override should forward to.
     virtual wxWindowList GetCompositeWindowParts() const = 0;
 
 private:
     // Must be implemented by the derived class to return all children to which
     // the public methods we override should forward to.
     virtual wxWindowList GetCompositeWindowParts() const = 0;
 
+    void OnWindowCreate(wxWindowCreateEvent& event)
+    {
+        event.Skip();
+
+        // Attach a few event handlers to all parts of the composite window.
+        // This makes the composite window behave more like a simple control
+        // and allows other code (such as wxDataViewCtrl's inline editing
+        // support) to hook into its event processing.
+
+        wxWindow *child = event.GetWindow();
+        if ( child == this )
+            return; // not a child, we don't want to Connect() to ourselves
+
+        // Always capture wxEVT_KILL_FOCUS:
+        child->Connect(wxEVT_KILL_FOCUS,
+                       wxFocusEventHandler(wxCompositeWindow::OnKillFocus),
+                       NULL, this);
+
+        // Some events should be only handled for non-toplevel children. For
+        // example, we want to close the control in wxDataViewCtrl when Enter
+        // is pressed in the inline editor, but not when it's pressed in a
+        // popup dialog it opens.
+        wxWindow *win = child;
+        while ( win && win != this )
+        {
+            if ( win->IsTopLevel() )
+                return;
+            win = win->GetParent();
+        }
+
+        child->Connect(wxEVT_CHAR,
+                       wxKeyEventHandler(wxCompositeWindow::OnChar),
+                       NULL, this);
+    }
+
+    void OnChar(wxKeyEvent& event)
+    {
+        if ( !this->ProcessWindowEvent(event) )
+            event.Skip();
+    }
+
+    void OnKillFocus(wxFocusEvent& event)
+    {
+        // Ignore focus changes within the composite control:
+        wxWindow *win = event.GetWindow();
+        while ( win )
+        {
+            if ( win == this )
+            {
+                event.Skip();
+                return;
+            }
+
+            // Note that we don't use IsTopLevel() check here, because we do
+            // want to ignore focus changes going to toplevel window that have
+            // the composite control as its parent; these would typically be
+            // some kind of control's popup window.
+            win = win->GetParent();
+        }
+
+        // The event shouldn't be ignored, forward it to the main control:
+        if ( !this->ProcessWindowEvent(event) )
+            event.Skip();
+    }
+
+#ifndef __VISUALC6__
+    template <class T>
+    void SetForAllParts(bool (wxWindowBase::*func)(const T&), const T& arg)
+    {
+        DoSetForAllParts<const T&>(func, arg);
+    }
+
+    template <class T>
+    void SetForAllParts(bool (wxWindowBase::*func)(T*), T* arg)
+    {
+        DoSetForAllParts<T*>(func, arg);
+    }
+
     template <class T>
     template <class T>
-    void DoSetForAllParts(bool (wxWindowBase::*func)(const T&), T arg)
+    void DoSetForAllParts(bool (wxWindowBase::*func)(T), T arg)
     {
         // Simply call the setters for all parts of this composite window.
         const wxWindowList parts = GetCompositeWindowParts();
     {
         // Simply call the setters for all parts of this composite window.
         const wxWindowList parts = GetCompositeWindowParts();
@@ -100,9 +215,14 @@ private:
         {
             wxWindow * const child = *i;
 
         {
             wxWindow * const child = *i;
 
-            (child->*func)(arg);
+            // Allow NULL elements in the list, this makes the code of derived
+            // composite controls which may have optionally shown children
+            // simpler and it doesn't cost us much here.
+            if ( child )
+                (child->*func)(arg);
         }
     }
         }
     }
+#endif // !__VISUALC6__
 
     wxDECLARE_NO_COPY_TEMPLATE_CLASS(wxCompositeWindow, W);
 };
 
     wxDECLARE_NO_COPY_TEMPLATE_CLASS(wxCompositeWindow, W);
 };