X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a9e41db760792a4e666492d77290f4c51e9c5b19..313509870731313f5091a973c3710110761904d4:/include/wx/compositewin.h diff --git a/include/wx/compositewin.h b/include/wx/compositewin.h index f5110ba9b9..567cd746bc 100644 --- a/include/wx/compositewin.h +++ b/include/wx/compositewin.h @@ -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 // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// @@ -12,6 +12,9 @@ #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 @@ -32,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. @@ -49,7 +70,7 @@ public: if ( !BaseWindowClass::SetForegroundColour(colour) ) return false; - DoSetForAllParts(&wxWindow::SetForegroundColour, colour); + SetForAllParts(&wxWindowBase::SetForegroundColour, colour); return true; } @@ -59,7 +80,7 @@ public: if ( !BaseWindowClass::SetBackgroundColour(colour) ) return false; - DoSetForAllParts(&wxWindow::SetBackgroundColour, colour); + SetForAllParts(&wxWindowBase::SetBackgroundColour, colour); return true; } @@ -69,7 +90,7 @@ public: if ( !BaseWindowClass::SetFont(font) ) return false; - DoSetForAllParts(&wxWindow::SetFont, font); + SetForAllParts(&wxWindowBase::SetFont, font); return true; } @@ -79,18 +100,112 @@ public: if ( !BaseWindowClass::SetCursor(cursor) ) return false; - DoSetForAllParts(&wxWindow::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 + void SetForAllParts(bool (wxWindowBase::*func)(const T&), const T& arg) + { + DoSetForAllParts(func, arg); + } + + template + void SetForAllParts(bool (wxWindowBase::*func)(T*), T* arg) + { + DoSetForAllParts(func, arg); + } + template - void DoSetForAllParts(bool (wxWindow::*func)(const T&), const 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(); @@ -100,9 +215,14 @@ private: { 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); };