]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/compositewin.h
Support using GetTextExtent() with empty string to get descent in wxOSX.
[wxWidgets.git] / include / wx / compositewin.h
index 9ac62639c2ace5804d40f7f28572d86bf6fa5b3b..567cd746bc86c14e39bbfeb4d6259e6429864609 100644 (file)
@@ -3,7 +3,7 @@
 // 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
 ///////////////////////////////////////////////////////////////////////////////
 #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
 //     officially stabilized unless you are ready to change it with the next
 //     wxWidgets release.
 
-// 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.
-#ifndef __VISUALC6__
-
 // ----------------------------------------------------------------------------
 // wxCompositeWindow is a helper for implementing composite windows: to define
 // a class using subwindows, simply inherit from it specialized with the real
@@ -42,7 +35,25 @@ public:
     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.
@@ -59,7 +70,7 @@ public:
         if ( !BaseWindowClass::SetForegroundColour(colour) )
             return false;
 
-        DoSetForAllParts(&wxWindowBase::SetForegroundColour, colour);
+        SetForAllParts(&wxWindowBase::SetForegroundColour, colour);
 
         return true;
     }
@@ -69,7 +80,7 @@ public:
         if ( !BaseWindowClass::SetBackgroundColour(colour) )
             return false;
 
-        DoSetForAllParts(&wxWindowBase::SetBackgroundColour, colour);
+        SetForAllParts(&wxWindowBase::SetBackgroundColour, colour);
 
         return true;
     }
@@ -79,7 +90,7 @@ public:
         if ( !BaseWindowClass::SetFont(font) )
             return false;
 
-        DoSetForAllParts(&wxWindowBase::SetFont, font);
+        SetForAllParts(&wxWindowBase::SetFont, font);
 
         return true;
     }
@@ -89,18 +100,112 @@ public:
         if ( !BaseWindowClass::SetCursor(cursor) )
             return false;
 
-        DoSetForAllParts(&wxWindowBase::SetCursor, cursor);
+        SetForAllParts(&wxWindowBase::SetCursor, cursor);
 
         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;
 
+    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 DoSetForAllParts(bool (wxWindowBase::*func)(const T&), const T& arg)
+    void SetForAllParts(bool (wxWindowBase::*func)(T*), T* arg)
+    {
+        DoSetForAllParts<T*>(func, arg);
+    }
+
+    template <class T>
+    void DoSetForAllParts(bool (wxWindowBase::*func)(T), T arg)
     {
         // Simply call the setters for all parts of this composite window.
         const wxWindowList parts = GetCompositeWindowParts();
@@ -117,17 +222,9 @@ private:
                 (child->*func)(arg);
         }
     }
+#endif // !__VISUALC6__
 
     wxDECLARE_NO_COPY_TEMPLATE_CLASS(wxCompositeWindow, W);
 };
 
-#else // __VISUALC6__
-
-template <class W>
-class wxCompositeWindow : public W
-{
-};
-
-#endif // !__VISUALC6__/__VISUALC6__
-
 #endif // _WX_COMPOSITEWIN_H_