add alt popup window style allowing to use keyboard and comboboxes in the popup window and use it for the generic date picker (patch 1582391 from Jaakko)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@42247 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -664,3 +664,15 @@ Show the popup.
|
|||||||
|
|
||||||
Undoes the last edit in the text field. Windows only.
|
Undoes the last edit in the text field. Windows only.
|
||||||
|
|
||||||
|
|
||||||
|
\membersection{wxComboCtrl::UseAltPopupWindow}\label{wxcomboctrlusealtpopupwindow}
|
||||||
|
|
||||||
|
\func{void}{UseAltPopupWindow}{\param{bool }{enable = true}}
|
||||||
|
|
||||||
|
Enable or disable usage of an alternative popup window, which guarantees
|
||||||
|
ability to focus the popup control, and allows common native controls to
|
||||||
|
function normally. This alternative popup window is usually a wxDialog,
|
||||||
|
and as such, when it is shown, its parent top-level window will appear
|
||||||
|
as if the focus has been lost from it.
|
||||||
|
|
||||||
|
|
||||||
|
@@ -83,7 +83,9 @@ enum
|
|||||||
// Internal use: SetTextIndent has been called
|
// Internal use: SetTextIndent has been called
|
||||||
wxCC_IFLAG_INDENT_SET = 0x0400,
|
wxCC_IFLAG_INDENT_SET = 0x0400,
|
||||||
// Internal use: Set wxTAB_TRAVERSAL to parent when popup is dismissed
|
// Internal use: Set wxTAB_TRAVERSAL to parent when popup is dismissed
|
||||||
wxCC_IFLAG_PARENT_TAB_TRAVERSAL = 0x0800
|
wxCC_IFLAG_PARENT_TAB_TRAVERSAL = 0x0800,
|
||||||
|
// Internal use: Secondary popup window type should be used (if available).
|
||||||
|
wxCC_IFLAG_USE_ALT_POPUP = 0x1000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -305,6 +307,21 @@ public:
|
|||||||
return m_tcArea;
|
return m_tcArea;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Call with enable as true to use a type of popup window that guarantees ability
|
||||||
|
// to focus the popup control, and normal function of common native controls.
|
||||||
|
// This alternative popup window is usually a wxDialog, and as such it's parent
|
||||||
|
// frame will appear as if the focus has been lost from it.
|
||||||
|
void UseAltPopupWindow( bool enable = true )
|
||||||
|
{
|
||||||
|
wxASSERT_MSG( !m_winPopup,
|
||||||
|
wxT("call this only before SetPopupControl") );
|
||||||
|
|
||||||
|
if ( enable )
|
||||||
|
m_iFlags |= wxCC_IFLAG_USE_ALT_POPUP;
|
||||||
|
else
|
||||||
|
m_iFlags &= ~wxCC_IFLAG_USE_ALT_POPUP;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Utilies needed by the popups or native implementations
|
// Utilies needed by the popups or native implementations
|
||||||
//
|
//
|
||||||
@@ -459,6 +476,9 @@ protected:
|
|||||||
// this is for the control in popup
|
// this is for the control in popup
|
||||||
wxEvtHandler* m_popupExtraHandler;
|
wxEvtHandler* m_popupExtraHandler;
|
||||||
|
|
||||||
|
// this is for the popup window
|
||||||
|
wxEvtHandler* m_popupWinEvtHandler;
|
||||||
|
|
||||||
// used to prevent immediate re-popupping incase closed popup
|
// used to prevent immediate re-popupping incase closed popup
|
||||||
// by clicking on the combo control (needed because of inconsistent
|
// by clicking on the combo control (needed because of inconsistent
|
||||||
// transient implementation across platforms).
|
// transient implementation across platforms).
|
||||||
@@ -527,6 +547,9 @@ private:
|
|||||||
|
|
||||||
wxByte m_ignoreEvtText; // Number of next EVT_TEXTs to ignore
|
wxByte m_ignoreEvtText; // Number of next EVT_TEXTs to ignore
|
||||||
|
|
||||||
|
// Is popup window wxPopupTransientWindow, wxPopupWindow or wxDialog?
|
||||||
|
wxByte m_popupWinType;
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
|
|
||||||
DECLARE_ABSTRACT_CLASS(wxComboCtrlBase)
|
DECLARE_ABSTRACT_CLASS(wxComboCtrlBase)
|
||||||
|
@@ -83,6 +83,8 @@ public:
|
|||||||
// log wxComboCtrl events
|
// log wxComboCtrl events
|
||||||
void OnComboBoxUpdate( wxCommandEvent& event );
|
void OnComboBoxUpdate( wxCommandEvent& event );
|
||||||
|
|
||||||
|
void OnIdle( wxIdleEvent& event );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
wxTextCtrl* m_logWin;
|
wxTextCtrl* m_logWin;
|
||||||
wxLog* m_logOld;
|
wxLog* m_logOld;
|
||||||
@@ -127,6 +129,8 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
|||||||
EVT_MENU(ComboControl_Compare, MyFrame::OnShowComparison)
|
EVT_MENU(ComboControl_Compare, MyFrame::OnShowComparison)
|
||||||
EVT_MENU(ComboControl_Quit, MyFrame::OnQuit)
|
EVT_MENU(ComboControl_Quit, MyFrame::OnQuit)
|
||||||
EVT_MENU(ComboControl_About, MyFrame::OnAbout)
|
EVT_MENU(ComboControl_About, MyFrame::OnAbout)
|
||||||
|
|
||||||
|
EVT_IDLE(MyFrame::OnIdle)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
// Create a new application object: this macro will allow wxWidgets to create
|
// Create a new application object: this macro will allow wxWidgets to create
|
||||||
@@ -729,6 +733,9 @@ MyFrame::MyFrame(const wxString& title)
|
|||||||
cc = new wxComboCtrl(panel,2,wxEmptyString,
|
cc = new wxComboCtrl(panel,2,wxEmptyString,
|
||||||
wxDefaultPosition, wxDefaultSize);
|
wxDefaultPosition, wxDefaultSize);
|
||||||
|
|
||||||
|
// Make sure we use popup that allows focusing the listview.
|
||||||
|
cc->UseAltPopupWindow();
|
||||||
|
|
||||||
cc->SetPopupMinWidth(300);
|
cc->SetPopupMinWidth(300);
|
||||||
|
|
||||||
ListViewComboPopup* iface = new ListViewComboPopup();
|
ListViewComboPopup* iface = new ListViewComboPopup();
|
||||||
@@ -749,6 +756,9 @@ MyFrame::MyFrame(const wxString& title)
|
|||||||
gcc = new wxGenericComboCtrl(panel,wxID_ANY,wxEmptyString,
|
gcc = new wxGenericComboCtrl(panel,wxID_ANY,wxEmptyString,
|
||||||
wxDefaultPosition, wxDefaultSize);
|
wxDefaultPosition, wxDefaultSize);
|
||||||
|
|
||||||
|
// Make sure we use popup that allows focusing the treectrl.
|
||||||
|
gcc->UseAltPopupWindow();
|
||||||
|
|
||||||
// Set popup interface right away, otherwise some of the calls
|
// Set popup interface right away, otherwise some of the calls
|
||||||
// below may fail
|
// below may fail
|
||||||
TreeCtrlComboPopup* tcPopup = new TreeCtrlComboPopup();
|
TreeCtrlComboPopup* tcPopup = new TreeCtrlComboPopup();
|
||||||
@@ -1059,3 +1069,27 @@ void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
|
|||||||
wxOK | wxICON_INFORMATION,
|
wxOK | wxICON_INFORMATION,
|
||||||
this);
|
this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnIdle(wxIdleEvent& event)
|
||||||
|
{
|
||||||
|
// This code is useful for debugging focus problems
|
||||||
|
// (which are plentiful when dealing with popup windows).
|
||||||
|
#if 0
|
||||||
|
static wxWindow* lastFocus = (wxWindow*) NULL;
|
||||||
|
|
||||||
|
wxWindow* curFocus = ::wxWindow::FindFocus();
|
||||||
|
|
||||||
|
if ( curFocus != lastFocus )
|
||||||
|
{
|
||||||
|
const wxChar* className = wxT("<none>");
|
||||||
|
if ( curFocus )
|
||||||
|
className = curFocus->GetClassInfo()->GetClassName();
|
||||||
|
lastFocus = curFocus;
|
||||||
|
wxLogDebug( wxT("FOCUSED: %s %X"),
|
||||||
|
className,
|
||||||
|
(unsigned int)curFocus);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
event.Skip();
|
||||||
|
}
|
||||||
|
@@ -62,6 +62,9 @@
|
|||||||
#if defined(__WXMSW__)
|
#if defined(__WXMSW__)
|
||||||
|
|
||||||
#define USE_TRANSIENT_POPUP 1 // Use wxPopupWindowTransient (preferred, if it works properly on platform)
|
#define USE_TRANSIENT_POPUP 1 // Use wxPopupWindowTransient (preferred, if it works properly on platform)
|
||||||
|
#define TRANSIENT_POPUPWIN_IS_PERFECT 0 // wxPopupTransientWindow works, its child can have focus, and common
|
||||||
|
// native controls work on it like normal.
|
||||||
|
#define POPUPWIN_IS_PERFECT 0 // Same, but for non-transient popup window.
|
||||||
#define TEXTCTRL_TEXT_CENTERED 0 // 1 if text in textctrl is vertically centered
|
#define TEXTCTRL_TEXT_CENTERED 0 // 1 if text in textctrl is vertically centered
|
||||||
|
|
||||||
//#undef wxUSE_POPUPWIN
|
//#undef wxUSE_POPUPWIN
|
||||||
@@ -69,17 +72,32 @@
|
|||||||
|
|
||||||
#elif defined(__WXGTK__)
|
#elif defined(__WXGTK__)
|
||||||
|
|
||||||
|
// NB: It is not recommended to use wxDialog as popup on wxGTK, because of
|
||||||
|
// this bug: If wxDialog is hidden, its position becomes corrupt
|
||||||
|
// between hide and next show, but without internal coordinates being
|
||||||
|
// reflected (or something like that - atleast commenting out ->Hide()
|
||||||
|
// seemed to eliminate the position change).
|
||||||
|
|
||||||
#define USE_TRANSIENT_POPUP 1 // Use wxPopupWindowTransient (preferred, if it works properly on platform)
|
#define USE_TRANSIENT_POPUP 1 // Use wxPopupWindowTransient (preferred, if it works properly on platform)
|
||||||
|
#define TRANSIENT_POPUPWIN_IS_PERFECT 0 // wxPopupTransientWindow works, its child can have focus, and common
|
||||||
|
// native controls work on it like normal.
|
||||||
|
#define POPUPWIN_IS_PERFECT 1 // Same, but for non-transient popup window.
|
||||||
#define TEXTCTRL_TEXT_CENTERED 1 // 1 if text in textctrl is vertically centered
|
#define TEXTCTRL_TEXT_CENTERED 1 // 1 if text in textctrl is vertically centered
|
||||||
|
|
||||||
#elif defined(__WXMAC__)
|
#elif defined(__WXMAC__)
|
||||||
|
|
||||||
#define USE_TRANSIENT_POPUP 0 // Use wxPopupWindowTransient (preferred, if it works properly on platform)
|
#define USE_TRANSIENT_POPUP 0 // Use wxPopupWindowTransient (preferred, if it works properly on platform)
|
||||||
|
#define TRANSIENT_POPUPWIN_IS_PERFECT 0 // wxPopupTransientWindow works, its child can have focus, and common
|
||||||
|
// native controls work on it like normal.
|
||||||
|
#define POPUPWIN_IS_PERFECT 0 // Same, but for non-transient popup window.
|
||||||
#define TEXTCTRL_TEXT_CENTERED 1 // 1 if text in textctrl is vertically centered
|
#define TEXTCTRL_TEXT_CENTERED 1 // 1 if text in textctrl is vertically centered
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define USE_TRANSIENT_POPUP 0 // Use wxPopupWindowTransient (preferred, if it works properly on platform)
|
#define USE_TRANSIENT_POPUP 0 // Use wxPopupWindowTransient (preferred, if it works properly on platform)
|
||||||
|
#define TRANSIENT_POPUPWIN_IS_PERFECT 0 // wxPopupTransientWindow works, its child can have focus, and common
|
||||||
|
// native controls work on it like normal.
|
||||||
|
#define POPUPWIN_IS_PERFECT 0 // Same, but for non-transient popup window.
|
||||||
#define TEXTCTRL_TEXT_CENTERED 1 // 1 if text in textctrl is vertically centered
|
#define TEXTCTRL_TEXT_CENTERED 1 // 1 if text in textctrl is vertically centered
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -102,24 +120,77 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Define different types of popup windows
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
POPUPWIN_NONE = 0,
|
||||||
|
POPUPWIN_WXPOPUPTRANSIENTWINDOW = 1,
|
||||||
|
POPUPWIN_WXPOPUPWINDOW = 2,
|
||||||
|
POPUPWIN_WXDIALOG = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#if USE_TRANSIENT_POPUP
|
#if USE_TRANSIENT_POPUP
|
||||||
|
// wxPopupTransientWindow is implemented
|
||||||
|
|
||||||
#define wxComboPopupWindowBase wxPopupTransientWindow
|
#define wxComboPopupWindowBase wxPopupTransientWindow
|
||||||
#define INSTALL_TOPLEV_HANDLER 0
|
#define PRIMARY_POPUP_TYPE POPUPWIN_WXPOPUPTRANSIENTWINDOW
|
||||||
|
#define USES_WXPOPUPTRANSIENTWINDOW 1
|
||||||
|
|
||||||
|
#if TRANSIENT_POPUPWIN_IS_PERFECT
|
||||||
|
//
|
||||||
|
#elif POPUPWIN_IS_PERFECT
|
||||||
|
#define wxComboPopupWindowBase2 wxPopupWindow
|
||||||
|
#define SECONDARY_POPUP_TYPE POPUPWIN_WXPOPUPWINDOW
|
||||||
|
#define USES_WXPOPUPWINDOW 1
|
||||||
|
#else
|
||||||
|
#define wxComboPopupWindowBase2 wxDialog
|
||||||
|
#define SECONDARY_POPUP_TYPE POPUPWIN_WXDIALOG
|
||||||
|
#define USES_WXDIALOG 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#elif wxUSE_POPUPWIN
|
#elif wxUSE_POPUPWIN
|
||||||
|
// wxPopupWindow (but not wxPopupTransientWindow) is properly implemented
|
||||||
|
|
||||||
#define wxComboPopupWindowBase wxPopupWindow
|
#define wxComboPopupWindowBase wxPopupWindow
|
||||||
#define INSTALL_TOPLEV_HANDLER 1
|
#define PRIMARY_POPUP_TYPE POPUPWIN_WXPOPUPWINDOW
|
||||||
|
#define USES_WXPOPUPWINDOW 1
|
||||||
|
|
||||||
|
#if !POPUPWIN_IS_PERFECT
|
||||||
|
#define wxComboPopupWindowBase2 wxDialog
|
||||||
|
#define SECONDARY_POPUP_TYPE POPUPWIN_WXDIALOG
|
||||||
|
#define USES_WXDIALOG 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
// wxPopupWindow is not implemented
|
||||||
|
|
||||||
#define wxComboPopupWindowBase wxDialog
|
#define wxComboPopupWindowBase wxDialog
|
||||||
#define INSTALL_TOPLEV_HANDLER 0 // Doesn't need since can monitor active event
|
#define PRIMARY_POPUP_TYPE POPUPWIN_WXDIALOG
|
||||||
|
#define USES_WXDIALOG 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef USES_WXPOPUPTRANSIENTWINDOW
|
||||||
|
#define USES_WXPOPUPTRANSIENTWINDOW 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef USES_WXPOPUPWINDOW
|
||||||
|
#define USES_WXPOPUPWINDOW 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef USES_WXDIALOG
|
||||||
|
#define USES_WXDIALOG 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if USES_WXPOPUPWINDOW
|
||||||
|
#define INSTALL_TOPLEV_HANDLER 1
|
||||||
|
#else
|
||||||
|
#define INSTALL_TOPLEV_HANDLER 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// ** TODO **
|
// ** TODO **
|
||||||
@@ -252,7 +323,7 @@ void wxComboFrameEventHandler::OnMove( wxMoveEvent& event )
|
|||||||
#endif // INSTALL_TOPLEV_HANDLER
|
#endif // INSTALL_TOPLEV_HANDLER
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxComboPopupWindow is wxPopupWindow customized for
|
// wxComboPopupWindow is, in essence, wxPopupWindow customized for
|
||||||
// wxComboCtrl.
|
// wxComboCtrl.
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -260,43 +331,9 @@ class wxComboPopupWindow : public wxComboPopupWindowBase
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
wxComboPopupWindow( wxComboCtrlBase *parent, int style = wxBORDER_NONE );
|
wxComboPopupWindow( wxComboCtrlBase *parent,
|
||||||
|
|
||||||
#if USE_TRANSIENT_POPUP
|
|
||||||
virtual bool ProcessLeftDown(wxMouseEvent& event);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void OnKeyEvent(wxKeyEvent& event);
|
|
||||||
|
|
||||||
void OnMouseEvent( wxMouseEvent& event );
|
|
||||||
#if !wxUSE_POPUPWIN
|
|
||||||
void OnActivate( wxActivateEvent& event );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
#if USE_TRANSIENT_POPUP
|
|
||||||
virtual void OnDismiss();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
|
||||||
DECLARE_EVENT_TABLE()
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(wxComboPopupWindow, wxComboPopupWindowBase)
|
|
||||||
EVT_MOUSE_EVENTS(wxComboPopupWindow::OnMouseEvent)
|
|
||||||
#if !wxUSE_POPUPWIN
|
|
||||||
EVT_ACTIVATE(wxComboPopupWindow::OnActivate)
|
|
||||||
#endif
|
|
||||||
EVT_KEY_DOWN(wxComboPopupWindow::OnKeyEvent)
|
|
||||||
EVT_KEY_UP(wxComboPopupWindow::OnKeyEvent)
|
|
||||||
END_EVENT_TABLE()
|
|
||||||
|
|
||||||
|
|
||||||
wxComboPopupWindow::wxComboPopupWindow( wxComboCtrlBase *parent,
|
|
||||||
int style )
|
int style )
|
||||||
#if wxUSE_POPUPWIN
|
#if USES_WXPOPUPWINDOW || USES_WXPOPUPTRANSIENTWINDOW
|
||||||
: wxComboPopupWindowBase(parent,style)
|
: wxComboPopupWindowBase(parent,style)
|
||||||
#else
|
#else
|
||||||
: wxComboPopupWindowBase(parent,
|
: wxComboPopupWindowBase(parent,
|
||||||
@@ -309,46 +346,20 @@ wxComboPopupWindow::wxComboPopupWindow( wxComboCtrlBase *parent,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxComboPopupWindow::OnKeyEvent( wxKeyEvent& event )
|
#if USES_WXPOPUPTRANSIENTWINDOW
|
||||||
{
|
virtual bool ProcessLeftDown(wxMouseEvent& event);
|
||||||
// Relay keyboard event to the main child controls
|
virtual void OnDismiss();
|
||||||
// (just skipping may just cause the popup to close)
|
|
||||||
wxWindowList children = GetChildren();
|
|
||||||
wxWindowList::iterator node = children.begin();
|
|
||||||
wxWindow* child = (wxWindow*)*node;
|
|
||||||
child->AddPendingEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxComboPopupWindow::OnMouseEvent( wxMouseEvent& event )
|
|
||||||
{
|
|
||||||
event.Skip();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !wxUSE_POPUPWIN
|
|
||||||
void wxComboPopupWindow::OnActivate( wxActivateEvent& event )
|
|
||||||
{
|
|
||||||
if ( !event.GetActive() )
|
|
||||||
{
|
|
||||||
// Tell combo control that we are dismissed.
|
|
||||||
wxComboCtrl* combo = (wxComboCtrl*) GetParent();
|
|
||||||
wxASSERT( combo );
|
|
||||||
wxASSERT( combo->IsKindOf(CLASSINFO(wxComboCtrl)) );
|
|
||||||
|
|
||||||
combo->HidePopup();
|
|
||||||
|
|
||||||
event.Skip();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if USE_TRANSIENT_POPUP
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if USES_WXPOPUPTRANSIENTWINDOW
|
||||||
bool wxComboPopupWindow::ProcessLeftDown(wxMouseEvent& event )
|
bool wxComboPopupWindow::ProcessLeftDown(wxMouseEvent& event )
|
||||||
{
|
{
|
||||||
return wxComboPopupWindowBase::ProcessLeftDown(event);
|
return wxComboPopupWindowBase::ProcessLeftDown(event);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if USE_TRANSIENT_POPUP
|
|
||||||
// First thing that happens when a transient popup closes is that this method gets called.
|
// First thing that happens when a transient popup closes is that this method gets called.
|
||||||
void wxComboPopupWindow::OnDismiss()
|
void wxComboPopupWindow::OnDismiss()
|
||||||
{
|
{
|
||||||
@@ -358,8 +369,68 @@ void wxComboPopupWindow::OnDismiss()
|
|||||||
|
|
||||||
combo->OnPopupDismiss();
|
combo->OnPopupDismiss();
|
||||||
}
|
}
|
||||||
|
#endif // USES_WXPOPUPTRANSIENTWINDOW
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxComboPopupWindowEvtHandler does bulk of the custom event handling
|
||||||
|
// of a popup window. It is separate so we can have different types
|
||||||
|
// of popup windows.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class wxComboPopupWindowEvtHandler : public wxEvtHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
wxComboPopupWindowEvtHandler( wxComboCtrlBase *parent )
|
||||||
|
{
|
||||||
|
m_combo = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnKeyEvent(wxKeyEvent& event);
|
||||||
|
#if USES_WXDIALOG
|
||||||
|
void OnActivate( wxActivateEvent& event );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxComboCtrlBase* m_combo;
|
||||||
|
|
||||||
|
DECLARE_EVENT_TABLE()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN_EVENT_TABLE(wxComboPopupWindowEvtHandler, wxEvtHandler)
|
||||||
|
EVT_KEY_DOWN(wxComboPopupWindowEvtHandler::OnKeyEvent)
|
||||||
|
EVT_KEY_UP(wxComboPopupWindowEvtHandler::OnKeyEvent)
|
||||||
|
#if USES_WXDIALOG
|
||||||
|
EVT_ACTIVATE(wxComboPopupWindowEvtHandler::OnActivate)
|
||||||
|
#endif
|
||||||
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
void wxComboPopupWindowEvtHandler::OnKeyEvent( wxKeyEvent& event )
|
||||||
|
{
|
||||||
|
// Relay keyboard event to the main child controls
|
||||||
|
wxWindowList children = m_combo->GetPopupWindow()->GetChildren();
|
||||||
|
wxWindowList::iterator node = children.begin();
|
||||||
|
wxWindow* child = (wxWindow*)*node;
|
||||||
|
child->AddPendingEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if USES_WXDIALOG
|
||||||
|
void wxComboPopupWindowEvtHandler::OnActivate( wxActivateEvent& event )
|
||||||
|
{
|
||||||
|
if ( !event.GetActive() )
|
||||||
|
{
|
||||||
|
// Tell combo control that we are dismissed.
|
||||||
|
m_combo->HidePopup();
|
||||||
|
|
||||||
|
event.Skip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxComboPopup
|
// wxComboPopup
|
||||||
//
|
//
|
||||||
@@ -639,6 +710,7 @@ void wxComboCtrlBase::Init()
|
|||||||
m_btnWidDefault = 0;
|
m_btnWidDefault = 0;
|
||||||
m_blankButtonBg = false;
|
m_blankButtonBg = false;
|
||||||
m_ignoreEvtText = 0;
|
m_ignoreEvtText = 0;
|
||||||
|
m_popupWinType = POPUPWIN_NONE;
|
||||||
m_btnWid = m_btnHei = -1;
|
m_btnWid = m_btnHei = -1;
|
||||||
m_btnSide = wxRIGHT;
|
m_btnSide = wxRIGHT;
|
||||||
m_btnSpacingX = 0;
|
m_btnSpacingX = 0;
|
||||||
@@ -1354,13 +1426,16 @@ bool wxComboCtrlBase::PreprocessMouseEvent( wxMouseEvent& event,
|
|||||||
wxLongLong t = ::wxGetLocalTimeMillis();
|
wxLongLong t = ::wxGetLocalTimeMillis();
|
||||||
int evtType = event.GetEventType();
|
int evtType = event.GetEventType();
|
||||||
|
|
||||||
#if !USE_TRANSIENT_POPUP
|
#if USES_WXPOPUPWINDOW || USES_WXDIALOG
|
||||||
|
if ( m_popupWinType != POPUPWIN_WXPOPUPTRANSIENTWINDOW )
|
||||||
|
{
|
||||||
if ( m_isPopupShown &&
|
if ( m_isPopupShown &&
|
||||||
( evtType == wxEVT_LEFT_DOWN || evtType == wxEVT_RIGHT_DOWN ) )
|
( evtType == wxEVT_LEFT_DOWN || evtType == wxEVT_RIGHT_DOWN ) )
|
||||||
{
|
{
|
||||||
HidePopup();
|
HidePopup();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Filter out clicks on button immediately after popup dismiss (Windows like behaviour)
|
// Filter out clicks on button immediately after popup dismiss (Windows like behaviour)
|
||||||
@@ -1382,10 +1457,9 @@ void wxComboCtrlBase::HandleNormalMouseEvent( wxMouseEvent& event )
|
|||||||
{
|
{
|
||||||
if ( m_isPopupShown )
|
if ( m_isPopupShown )
|
||||||
{
|
{
|
||||||
#if !wxUSE_POPUPWIN
|
#if USES_WXPOPUPWINDOW
|
||||||
// Normally do nothing - evt handler should close it for us
|
|
||||||
#elif !USE_TRANSIENT_POPUP
|
|
||||||
// Click here always hides the popup.
|
// Click here always hides the popup.
|
||||||
|
if ( m_popupWinType == POPUPWIN_WXPOPUPWINDOW )
|
||||||
HidePopup();
|
HidePopup();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -1495,7 +1569,28 @@ void wxComboCtrlBase::CreatePopup()
|
|||||||
wxWindow* popup;
|
wxWindow* popup;
|
||||||
|
|
||||||
if ( !m_winPopup )
|
if ( !m_winPopup )
|
||||||
|
{
|
||||||
|
#ifdef wxComboPopupWindowBase2
|
||||||
|
if ( m_iFlags & wxCC_IFLAG_USE_ALT_POPUP )
|
||||||
|
{
|
||||||
|
#if !USES_WXDIALOG
|
||||||
|
m_winPopup = new wxComboPopupWindowBase2( this, wxNO_BORDER );
|
||||||
|
#else
|
||||||
|
m_winPopup = new wxComboPopupWindowBase2( this, wxID_ANY, wxEmptyString,
|
||||||
|
wxPoint(-21,-21), wxSize(20, 20),
|
||||||
|
wxNO_BORDER );
|
||||||
|
#endif
|
||||||
|
m_popupWinType = SECONDARY_POPUP_TYPE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
m_winPopup = new wxComboPopupWindow( this, wxNO_BORDER );
|
m_winPopup = new wxComboPopupWindow( this, wxNO_BORDER );
|
||||||
|
m_popupWinType = PRIMARY_POPUP_TYPE;
|
||||||
|
}
|
||||||
|
m_popupWinEvtHandler = new wxComboPopupWindowEvtHandler(this);
|
||||||
|
m_winPopup->PushEventHandler(m_popupWinEvtHandler);
|
||||||
|
}
|
||||||
|
|
||||||
popupInterface->Create(m_winPopup);
|
popupInterface->Create(m_winPopup);
|
||||||
m_popup = popup = popupInterface->GetControl();
|
m_popup = popup = popupInterface->GetControl();
|
||||||
@@ -1524,7 +1619,12 @@ void wxComboCtrlBase::DestroyPopup()
|
|||||||
delete m_popupInterface;
|
delete m_popupInterface;
|
||||||
|
|
||||||
if ( m_winPopup )
|
if ( m_winPopup )
|
||||||
|
{
|
||||||
|
m_winPopup->RemoveEventHandler(m_popupWinEvtHandler);
|
||||||
|
delete m_popupWinEvtHandler;
|
||||||
|
m_popupWinEvtHandler = NULL;
|
||||||
m_winPopup->Destroy();
|
m_winPopup->Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
m_popupExtraHandler = (wxEvtHandler*) NULL;
|
m_popupExtraHandler = (wxEvtHandler*) NULL;
|
||||||
m_popupInterface = (wxComboPopup*) NULL;
|
m_popupInterface = (wxComboPopup*) NULL;
|
||||||
@@ -1728,14 +1828,17 @@ void wxComboCtrlBase::ShowPopup()
|
|||||||
m_isPopupShown = true;
|
m_isPopupShown = true;
|
||||||
|
|
||||||
// Show it
|
// Show it
|
||||||
#if USE_TRANSIENT_POPUP
|
#if USES_WXPOPUPTRANSIENTWINDOW
|
||||||
|
if ( m_popupWinType == POPUPWIN_WXPOPUPTRANSIENTWINDOW )
|
||||||
((wxPopupTransientWindow*)winPopup)->Popup(popup);
|
((wxPopupTransientWindow*)winPopup)->Popup(popup);
|
||||||
#else
|
else
|
||||||
winPopup->Show();
|
|
||||||
#endif
|
#endif
|
||||||
|
winPopup->Show();
|
||||||
|
|
||||||
#if INSTALL_TOPLEV_HANDLER
|
#if INSTALL_TOPLEV_HANDLER
|
||||||
// Put top level window event handler into place
|
// Put top level window event handler into place
|
||||||
|
if ( m_popupWinType == POPUPWIN_WXPOPUPWINDOW )
|
||||||
|
{
|
||||||
if ( !m_toplevEvtHandler )
|
if ( !m_toplevEvtHandler )
|
||||||
m_toplevEvtHandler = new wxComboFrameEventHandler(this);
|
m_toplevEvtHandler = new wxComboFrameEventHandler(this);
|
||||||
|
|
||||||
@@ -1743,6 +1846,7 @@ void wxComboCtrlBase::ShowPopup()
|
|||||||
wxASSERT( toplev );
|
wxASSERT( toplev );
|
||||||
((wxComboFrameEventHandler*)m_toplevEvtHandler)->OnPopup();
|
((wxComboFrameEventHandler*)m_toplevEvtHandler)->OnPopup();
|
||||||
toplev->PushEventHandler( m_toplevEvtHandler );
|
toplev->PushEventHandler( m_toplevEvtHandler );
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1753,7 +1857,18 @@ void wxComboCtrlBase::OnPopupDismiss()
|
|||||||
if ( !m_isPopupShown )
|
if ( !m_isPopupShown )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// *Must* set this before focus etc.
|
// NB: Focus setting is really funny, atleast on wxMSW. First of all,
|
||||||
|
// we need to have SetFocus at the end. Otherwise wxTextCtrl may
|
||||||
|
// freeze until focus goes somewhere else. Second, wxTreeCtrl as
|
||||||
|
// popup, when dismissing, "steals" focus back to itself unless
|
||||||
|
// SetFocus is called also here, exactly before m_isPopupShown
|
||||||
|
// is set to false. Which is truly weird since SetFocus is just
|
||||||
|
// wxWindowMSW method and does not call event handler or anything like
|
||||||
|
// that (ie. does not care about m_isPopupShown).
|
||||||
|
|
||||||
|
SetFocus();
|
||||||
|
|
||||||
|
// This should preferably be set before focus.
|
||||||
m_isPopupShown = false;
|
m_isPopupShown = false;
|
||||||
|
|
||||||
// Inform popup control itself
|
// Inform popup control itself
|
||||||
@@ -1791,10 +1906,7 @@ void wxComboCtrlBase::OnPopupDismiss()
|
|||||||
// refresh control (necessary even if m_text)
|
// refresh control (necessary even if m_text)
|
||||||
Refresh();
|
Refresh();
|
||||||
|
|
||||||
#if !wxUSE_POPUPWIN
|
|
||||||
SetFocus();
|
SetFocus();
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxComboCtrlBase::HidePopup()
|
void wxComboCtrlBase::HidePopup()
|
||||||
@@ -1807,11 +1919,12 @@ void wxComboCtrlBase::HidePopup()
|
|||||||
// transfer value and show it in textctrl, if any
|
// transfer value and show it in textctrl, if any
|
||||||
SetValue( m_popupInterface->GetStringValue() );
|
SetValue( m_popupInterface->GetStringValue() );
|
||||||
|
|
||||||
#if USE_TRANSIENT_POPUP
|
#if USES_WXPOPUPTRANSIENTWINDOW
|
||||||
|
if ( m_popupWinType == POPUPWIN_WXPOPUPTRANSIENTWINDOW )
|
||||||
((wxPopupTransientWindow*)m_winPopup)->Dismiss();
|
((wxPopupTransientWindow*)m_winPopup)->Dismiss();
|
||||||
#else
|
else
|
||||||
m_winPopup->Hide();
|
|
||||||
#endif
|
#endif
|
||||||
|
m_winPopup->Hide();
|
||||||
|
|
||||||
OnPopupDismiss();
|
OnPopupDismiss();
|
||||||
}
|
}
|
||||||
|
@@ -561,7 +561,7 @@ void wxPopupFocusHandler::OnKillFocus(wxFocusEvent& event)
|
|||||||
void wxPopupFocusHandler::OnKeyDown(wxKeyEvent& event)
|
void wxPopupFocusHandler::OnKeyDown(wxKeyEvent& event)
|
||||||
{
|
{
|
||||||
// let the window have it first, it might process the keys
|
// let the window have it first, it might process the keys
|
||||||
if ( !m_popup->ProcessEvent(event) )
|
if ( !m_popup->GetEventHandler()->ProcessEvent(event) )
|
||||||
{
|
{
|
||||||
// by default, dismiss the popup
|
// by default, dismiss the popup
|
||||||
m_popup->DismissAndNotify();
|
m_popup->DismissAndNotify();
|
||||||
|
@@ -414,6 +414,10 @@ bool wxDatePickerCtrlGeneric::Create(wxWindow *parent,
|
|||||||
|
|
||||||
m_popup = new wxCalendarComboPopup();
|
m_popup = new wxCalendarComboPopup();
|
||||||
|
|
||||||
|
#if defined(__WXMSW__)
|
||||||
|
// without this keyboard navigation in month control doesn't work
|
||||||
|
m_combo->UseAltPopupWindow();
|
||||||
|
#endif
|
||||||
m_combo->SetPopupControl(m_popup);
|
m_combo->SetPopupControl(m_popup);
|
||||||
|
|
||||||
m_cal = m_popup;
|
m_cal = m_popup;
|
||||||
|
Reference in New Issue
Block a user