1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/compositewin.h
3 // Purpose: wxCompositeWindow<> declaration
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 #ifndef _WX_COMPOSITEWIN_H_
12 #define _WX_COMPOSITEWIN_H_
14 #include "wx/window.h"
15 #include "wx/containr.h"
17 class WXDLLIMPEXP_FWD_CORE wxToolTip
;
19 // NB: This is an experimental and, as for now, undocumented class used only by
20 // wxWidgets itself internally. Don't use it in your code until its API is
21 // officially stabilized unless you are ready to change it with the next
24 // ----------------------------------------------------------------------------
25 // wxCompositeWindow is a helper for implementing composite windows: to define
26 // a class using subwindows, simply inherit from it specialized with the real
27 // base class name and implement GetCompositeWindowParts() pure virtual method.
28 // ----------------------------------------------------------------------------
30 // The template parameter W must be a wxWindow-derived class.
32 class wxCompositeWindow
: public W
35 typedef W BaseWindowClass
;
37 // Default ctor doesn't do anything.
43 wxWindowCreateEventHandler(wxCompositeWindow::OnWindowCreate
)
49 // FIXME-VC6: This compiler can't compile DoSetForAllParts() template function,
50 // it can't determine whether the deduced type should be "T" or "const T&". And
51 // without this function wxCompositeWindow is pretty useless so simply disable
52 // this code for it, this does mean that setting colours/fonts/... for
53 // composite controls won't work in the library compiled with it but so far
54 // this only affects the generic wxDatePickerCtrl which is not used by default
55 // under MSW anyhow so it doesn't seem to be worth it to spend time and uglify
56 // the code to fix it.
58 // Override all wxWindow methods which must be forwarded to the composite
61 // Attribute setters group.
63 // NB: Unfortunately we can't factor out the call for the setter itself
64 // into DoSetForAllParts() because we can't call the function passed to
65 // it non-virtually and we need to do this to avoid infinite recursion,
66 // so we work around this by calling the method of this object itself
67 // manually in each function.
68 virtual bool SetForegroundColour(const wxColour
& colour
)
70 if ( !BaseWindowClass::SetForegroundColour(colour
) )
73 SetForAllParts(&wxWindowBase::SetForegroundColour
, colour
);
78 virtual bool SetBackgroundColour(const wxColour
& colour
)
80 if ( !BaseWindowClass::SetBackgroundColour(colour
) )
83 SetForAllParts(&wxWindowBase::SetBackgroundColour
, colour
);
88 virtual bool SetFont(const wxFont
& font
)
90 if ( !BaseWindowClass::SetFont(font
) )
93 SetForAllParts(&wxWindowBase::SetFont
, font
);
98 virtual bool SetCursor(const wxCursor
& cursor
)
100 if ( !BaseWindowClass::SetCursor(cursor
) )
103 SetForAllParts(&wxWindowBase::SetCursor
, cursor
);
109 virtual void DoSetToolTip(wxToolTip
*tip
)
111 BaseWindowClass::DoSetToolTip(tip
);
113 SetForAllParts(&wxWindowBase::CopyToolTip
, tip
);
115 #endif // wxUSE_TOOLTIPS
117 #endif // !__VISUALC6__
119 virtual void SetFocus()
121 wxSetFocusToChild(this, NULL
);
125 // Must be implemented by the derived class to return all children to which
126 // the public methods we override should forward to.
127 virtual wxWindowList
GetCompositeWindowParts() const = 0;
129 void OnWindowCreate(wxWindowCreateEvent
& event
)
133 // Attach a few event handlers to all parts of the composite window.
134 // This makes the composite window behave more like a simple control
135 // and allows other code (such as wxDataViewCtrl's inline editing
136 // support) to hook into its event processing.
138 wxWindow
*child
= event
.GetWindow();
140 return; // not a child, we don't want to Connect() to ourselves
142 // Always capture wxEVT_KILL_FOCUS:
143 child
->Connect(wxEVT_KILL_FOCUS
,
144 wxFocusEventHandler(wxCompositeWindow::OnKillFocus
),
147 // Some events should be only handled for non-toplevel children. For
148 // example, we want to close the control in wxDataViewCtrl when Enter
149 // is pressed in the inline editor, but not when it's pressed in a
150 // popup dialog it opens.
151 wxWindow
*win
= child
;
152 while ( win
&& win
!= this )
154 if ( win
->IsTopLevel() )
156 win
= win
->GetParent();
159 child
->Connect(wxEVT_CHAR
,
160 wxKeyEventHandler(wxCompositeWindow::OnChar
),
164 void OnChar(wxKeyEvent
& event
)
166 if ( !this->ProcessWindowEvent(event
) )
170 void OnKillFocus(wxFocusEvent
& event
)
172 // Ignore focus changes within the composite control:
173 wxWindow
*win
= event
.GetWindow();
182 // Note that we don't use IsTopLevel() check here, because we do
183 // want to ignore focus changes going to toplevel window that have
184 // the composite control as its parent; these would typically be
185 // some kind of control's popup window.
186 win
= win
->GetParent();
189 // The event shouldn't be ignored, forward it to the main control:
190 if ( !this->ProcessWindowEvent(event
) )
196 void SetForAllParts(bool (wxWindowBase::*func
)(const T
&), const T
& arg
)
198 DoSetForAllParts
<const T
&>(func
, arg
);
202 void SetForAllParts(bool (wxWindowBase::*func
)(T
*), T
* arg
)
204 DoSetForAllParts
<T
*>(func
, arg
);
208 void DoSetForAllParts(bool (wxWindowBase::*func
)(T
), T arg
)
210 // Simply call the setters for all parts of this composite window.
211 const wxWindowList parts
= GetCompositeWindowParts();
212 for ( wxWindowList::const_iterator i
= parts
.begin();
216 wxWindow
* const child
= *i
;
218 // Allow NULL elements in the list, this makes the code of derived
219 // composite controls which may have optionally shown children
220 // simpler and it doesn't cost us much here.
225 #endif // !__VISUALC6__
227 wxDECLARE_NO_COPY_TEMPLATE_CLASS(wxCompositeWindow
, W
);
230 #endif // _WX_COMPOSITEWIN_H_