Allow using wxCompositeWindow<T> as wxDataViewCtrl inline editor.

wxDVC inline editing code attaches some event handlers to the editor
control; most importantly, it watches for Enter key and for focus
changes. If the editor control is a composite window, these events occur
in a sub control and never reach wxDVC code.

Fix this by forwarding events to the main window of the composite
control. Only events required by wxDVC are implemented for now.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@69470 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2011-10-19 16:20:01 +00:00
parent 8df14bedf5
commit 31af22fa2d
2 changed files with 95 additions and 21 deletions

View File

@@ -12,6 +12,7 @@
#define _WX_COMPOSITEWIN_H_ #define _WX_COMPOSITEWIN_H_
#include "wx/window.h" #include "wx/window.h"
#include "wx/containr.h"
class WXDLLIMPEXP_FWD_CORE wxToolTip; class WXDLLIMPEXP_FWD_CORE wxToolTip;
@@ -20,16 +21,6 @@ class WXDLLIMPEXP_FWD_CORE wxToolTip;
// officially stabilized unless you are ready to change it with the next // officially stabilized unless you are ready to change it with the next
// wxWidgets release. // 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 // wxCompositeWindow is a helper for implementing composite windows: to define
// a class using subwindows, simply inherit from it specialized with the real // a class using subwindows, simply inherit from it specialized with the real
@@ -44,7 +35,25 @@ public:
typedef W BaseWindowClass; typedef W BaseWindowClass;
// Default ctor doesn't do anything. // 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 // Override all wxWindow methods which must be forwarded to the composite
// window parts. // window parts.
@@ -105,11 +114,84 @@ public:
} }
#endif // wxUSE_TOOLTIPS #endif // wxUSE_TOOLTIPS
#endif // !__VISUALC6__
virtual void SetFocus()
{
wxSetFocusToChild(this, NULL);
}
private: private:
// Must be implemented by the derived class to return all children to which // Must be implemented by the derived class to return all children to which
// the public methods we override should forward to. // the public methods we override should forward to.
virtual wxWindowList GetCompositeWindowParts() const = 0; 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> template <class T>
void SetForAllParts(bool (wxWindowBase::*func)(const T&), const T& arg) void SetForAllParts(bool (wxWindowBase::*func)(const T&), const T& arg)
{ {
@@ -140,17 +222,9 @@ private:
(child->*func)(arg); (child->*func)(arg);
} }
} }
#endif // !__VISUALC6__
wxDECLARE_NO_COPY_TEMPLATE_CLASS(wxCompositeWindow, W); wxDECLARE_NO_COPY_TEMPLATE_CLASS(wxCompositeWindow, W);
}; };
#else // __VISUALC6__
template <class W>
class wxCompositeWindow : public W
{
};
#endif // !__VISUALC6__/__VISUALC6__
#endif // _WX_COMPOSITEWIN_H_ #endif // _WX_COMPOSITEWIN_H_

View File

@@ -148,7 +148,7 @@ protected:
#endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL #endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
// this function is for wxWidgets internal use only // this function is for wxWidgets internal use only
extern bool wxSetFocusToChild(wxWindow *win, wxWindow **child); extern WXDLLIMPEXP_CORE bool wxSetFocusToChild(wxWindow *win, wxWindow **child);
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxNavigationEnabled: Derive from this class to support keyboard navigation // wxNavigationEnabled: Derive from this class to support keyboard navigation