1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/compositewin.h
3 // Purpose: wxCompositeWindow<> declaration
4 // Author: Vadim Zeitlin
6 // Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
10 #ifndef _WX_COMPOSITEWIN_H_
11 #define _WX_COMPOSITEWIN_H_
13 #include "wx/window.h"
14 #include "wx/containr.h"
16 class WXDLLIMPEXP_FWD_CORE wxToolTip
;
18 // NB: This is an experimental and, as for now, undocumented class used only by
19 // wxWidgets itself internally. Don't use it in your code until its API is
20 // officially stabilized unless you are ready to change it with the next
23 // ----------------------------------------------------------------------------
24 // wxCompositeWindow is a helper for implementing composite windows: to define
25 // a class using subwindows, simply inherit from it specialized with the real
26 // base class name and implement GetCompositeWindowParts() pure virtual method.
27 // ----------------------------------------------------------------------------
29 // The template parameter W must be a wxWindow-derived class.
31 class wxCompositeWindow
: public W
34 typedef W BaseWindowClass
;
36 // Default ctor doesn't do anything.
42 wxWindowCreateEventHandler(wxCompositeWindow::OnWindowCreate
)
48 // FIXME-VC6: This compiler can't compile DoSetForAllParts() template function,
49 // it can't determine whether the deduced type should be "T" or "const T&". And
50 // without this function wxCompositeWindow is pretty useless so simply disable
51 // this code for it, this does mean that setting colours/fonts/... for
52 // composite controls won't work in the library compiled with it but so far
53 // this only affects the generic wxDatePickerCtrl which is not used by default
54 // under MSW anyhow so it doesn't seem to be worth it to spend time and uglify
55 // the code to fix it.
57 // Override all wxWindow methods which must be forwarded to the composite
60 // Attribute setters group.
62 // NB: Unfortunately we can't factor out the call for the setter itself
63 // into DoSetForAllParts() because we can't call the function passed to
64 // it non-virtually and we need to do this to avoid infinite recursion,
65 // so we work around this by calling the method of this object itself
66 // manually in each function.
67 virtual bool SetForegroundColour(const wxColour
& colour
)
69 if ( !BaseWindowClass::SetForegroundColour(colour
) )
72 SetForAllParts(&wxWindowBase::SetForegroundColour
, colour
);
77 virtual bool SetBackgroundColour(const wxColour
& colour
)
79 if ( !BaseWindowClass::SetBackgroundColour(colour
) )
82 SetForAllParts(&wxWindowBase::SetBackgroundColour
, colour
);
87 virtual bool SetFont(const wxFont
& font
)
89 if ( !BaseWindowClass::SetFont(font
) )
92 SetForAllParts(&wxWindowBase::SetFont
, font
);
97 virtual bool SetCursor(const wxCursor
& cursor
)
99 if ( !BaseWindowClass::SetCursor(cursor
) )
102 SetForAllParts(&wxWindowBase::SetCursor
, cursor
);
108 virtual void DoSetToolTip(wxToolTip
*tip
)
110 BaseWindowClass::DoSetToolTip(tip
);
112 SetForAllParts(&wxWindowBase::CopyToolTip
, tip
);
114 #endif // wxUSE_TOOLTIPS
116 #endif // !__VISUALC6__
118 virtual void SetFocus()
120 wxSetFocusToChild(this, NULL
);
124 // Must be implemented by the derived class to return all children to which
125 // the public methods we override should forward to.
126 virtual wxWindowList
GetCompositeWindowParts() const = 0;
128 void OnWindowCreate(wxWindowCreateEvent
& event
)
132 // Attach a few event handlers to all parts of the composite window.
133 // This makes the composite window behave more like a simple control
134 // and allows other code (such as wxDataViewCtrl's inline editing
135 // support) to hook into its event processing.
137 wxWindow
*child
= event
.GetWindow();
139 return; // not a child, we don't want to Connect() to ourselves
141 // Always capture wxEVT_KILL_FOCUS:
142 child
->Connect(wxEVT_KILL_FOCUS
,
143 wxFocusEventHandler(wxCompositeWindow::OnKillFocus
),
146 // Some events should be only handled for non-toplevel children. For
147 // example, we want to close the control in wxDataViewCtrl when Enter
148 // is pressed in the inline editor, but not when it's pressed in a
149 // popup dialog it opens.
150 wxWindow
*win
= child
;
151 while ( win
&& win
!= this )
153 if ( win
->IsTopLevel() )
155 win
= win
->GetParent();
158 child
->Connect(wxEVT_CHAR
,
159 wxKeyEventHandler(wxCompositeWindow::OnChar
),
163 void OnChar(wxKeyEvent
& event
)
165 if ( !this->ProcessWindowEvent(event
) )
169 void OnKillFocus(wxFocusEvent
& event
)
171 // Ignore focus changes within the composite control:
172 wxWindow
*win
= event
.GetWindow();
181 // Note that we don't use IsTopLevel() check here, because we do
182 // want to ignore focus changes going to toplevel window that have
183 // the composite control as its parent; these would typically be
184 // some kind of control's popup window.
185 win
= win
->GetParent();
188 // The event shouldn't be ignored, forward it to the main control:
189 if ( !this->ProcessWindowEvent(event
) )
195 void SetForAllParts(bool (wxWindowBase::*func
)(const T
&), const T
& arg
)
197 DoSetForAllParts
<const T
&>(func
, arg
);
201 void SetForAllParts(bool (wxWindowBase::*func
)(T
*), T
* arg
)
203 DoSetForAllParts
<T
*>(func
, arg
);
207 void DoSetForAllParts(bool (wxWindowBase::*func
)(T
), T arg
)
209 // Simply call the setters for all parts of this composite window.
210 const wxWindowList parts
= GetCompositeWindowParts();
211 for ( wxWindowList::const_iterator i
= parts
.begin();
215 wxWindow
* const child
= *i
;
217 // Allow NULL elements in the list, this makes the code of derived
218 // composite controls which may have optionally shown children
219 // simpler and it doesn't cost us much here.
224 #endif // !__VISUALC6__
226 wxDECLARE_NO_COPY_TEMPLATE_CLASS(wxCompositeWindow
, W
);
229 #endif // _WX_COMPOSITEWIN_H_