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:
@@ -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_
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user