[ 1584680 ] wxComboCtrl Popup Animation
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@42407 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -213,6 +213,25 @@ appropriately.}
|
|||||||
Destructor, destroying the combo control.
|
Destructor, destroying the combo control.
|
||||||
|
|
||||||
|
|
||||||
|
\membersection{wxComboCtrl::AnimateShow}\label{wxcomboctrlanimateshow}
|
||||||
|
|
||||||
|
\func{virtual bool}{AnimateShow}{\param{const wxRect\& }{rect}, \param{int }{flags}}
|
||||||
|
|
||||||
|
This member function is not normally called in application code.
|
||||||
|
Instead, it can be implemented in a derived class to create a
|
||||||
|
custom popup animation.
|
||||||
|
|
||||||
|
\wxheading{Parameters}
|
||||||
|
|
||||||
|
Same as in \helpref{DoShowPopup}{wxcomboctrldoshowpopup}.
|
||||||
|
|
||||||
|
\wxheading{Return value}
|
||||||
|
|
||||||
|
\true if animation finishes before the function returns.
|
||||||
|
\false otherwise. In the latter case you need to manually call DoShowPopup
|
||||||
|
after the animation ends.
|
||||||
|
|
||||||
|
|
||||||
\membersection{wxComboCtrl::Create}\label{wxcomboctrlcreate}
|
\membersection{wxComboCtrl::Create}\label{wxcomboctrlcreate}
|
||||||
|
|
||||||
\func{bool}{Create}{\param{wxWindow*}{ parent}, \param{wxWindowID}{ id},\rtfsp
|
\func{bool}{Create}{\param{wxWindow*}{ parent}, \param{wxWindowID}{ id},\rtfsp
|
||||||
@@ -251,6 +270,31 @@ something else than show the popup, then DoSetPopupControl
|
|||||||
must always return NULL.
|
must always return NULL.
|
||||||
|
|
||||||
|
|
||||||
|
\membersection{wxComboCtrl::DoShowPopup}\label{wxcomboctrldoshowpopup}
|
||||||
|
|
||||||
|
\func{virtual void}{DoShowPopup}{\param{const wxRect\& }{rect}, \param{int }{flags}}
|
||||||
|
|
||||||
|
This member function is not normally called in application code.
|
||||||
|
Instead, it must be called in a derived class to make sure popup
|
||||||
|
is properly shown after a popup animation has finished (but only
|
||||||
|
if \helpref{AnimateShow}{wxcomboctrlanimateshow} did not finish
|
||||||
|
the animation within it's function scope).
|
||||||
|
|
||||||
|
\wxheading{Parameters}
|
||||||
|
|
||||||
|
\docparam{rect}{Position to show the popup window at, in screen coordinates.}
|
||||||
|
|
||||||
|
\docparam{flags}{Combination of any of the following:}
|
||||||
|
\twocolwidtha{8cm}%
|
||||||
|
\begin{twocollist}\itemsep=0pt
|
||||||
|
\twocolitem{{\tt wxComboCtrl::ShowAbove}}{Popup is shown above the control instead
|
||||||
|
of below.}
|
||||||
|
\twocolitem{{\tt wxComboCtrl::CanDeferShow}}{Showing the popup can be deferred
|
||||||
|
to happen sometime after \helpref{ShowPopup}{wxcomboctrlshowpopup} has finished.
|
||||||
|
In this case, \helpref{AnimateShow}{wxcomboctrlanimateshow} must return \false.}
|
||||||
|
\end{twocollist}
|
||||||
|
|
||||||
|
|
||||||
\membersection{wxComboCtrl::GetBitmapDisabled}\label{wxcomboctrlgetbitmapdisabled}
|
\membersection{wxComboCtrl::GetBitmapDisabled}\label{wxcomboctrlgetbitmapdisabled}
|
||||||
|
|
||||||
\constfunc{const wxBitmap\&}{GetBitmapDisabled}{\void}
|
\constfunc{const wxBitmap\&}{GetBitmapDisabled}{\void}
|
||||||
@@ -361,6 +405,22 @@ Returns the insertion point for the combo control's text field.
|
|||||||
doesn't have the focus.
|
doesn't have the focus.
|
||||||
|
|
||||||
|
|
||||||
|
\membersection{wxComboCtrl::IsPopupWindowState}\label{wxcomboctrlispopupwindowstate}
|
||||||
|
|
||||||
|
\constfunc{bool}{IsPopupWindowState}{\param{int }{state}}
|
||||||
|
|
||||||
|
Returns \true if the popup window is in the given state.
|
||||||
|
Possible values are:
|
||||||
|
\twocolwidtha{8cm}%
|
||||||
|
\begin{twocollist}\itemsep=0pt
|
||||||
|
\twocolitem{{\tt wxComboCtrl::Hidden}}{Popup window is hidden.}
|
||||||
|
\twocolitem{{\tt wxComboCtrl::Animating}}{Popup window is being shown, but the
|
||||||
|
popup animation has not yet finished.}
|
||||||
|
\twocolitem{{\tt wxComboCtrl::Visible}}{Popup window is fully visible.}
|
||||||
|
\end{twocollist}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
\membersection{wxComboCtrl::GetLastPosition}\label{wxcomboctrlgetlastposition}
|
\membersection{wxComboCtrl::GetLastPosition}\label{wxcomboctrlgetlastposition}
|
||||||
|
|
||||||
\constfunc{long}{GetLastPosition}{\void}
|
\constfunc{long}{GetLastPosition}{\void}
|
||||||
|
@@ -152,7 +152,7 @@ public:
|
|||||||
virtual void OnButtonClick();
|
virtual void OnButtonClick();
|
||||||
|
|
||||||
// return true if the popup is currently shown
|
// return true if the popup is currently shown
|
||||||
bool IsPopupShown() const { return m_isPopupShown; }
|
bool IsPopupShown() const { return m_popupWinState == Visible; }
|
||||||
|
|
||||||
// set interface class instance derived from wxComboPopup
|
// set interface class instance derived from wxComboPopup
|
||||||
// NULL popup can be used to indicate default in a derived class
|
// NULL popup can be used to indicate default in a derived class
|
||||||
@@ -350,7 +350,7 @@ public:
|
|||||||
bool ShouldDrawFocus() const
|
bool ShouldDrawFocus() const
|
||||||
{
|
{
|
||||||
const wxWindow* curFocus = FindFocus();
|
const wxWindow* curFocus = FindFocus();
|
||||||
return ( !m_isPopupShown &&
|
return ( !IsPopupShown() &&
|
||||||
(curFocus == this || (m_btn && curFocus == m_btn)) &&
|
(curFocus == this || (m_btn && curFocus == m_btn)) &&
|
||||||
(m_windowStyle & wxCB_READONLY) );
|
(m_windowStyle & wxCB_READONLY) );
|
||||||
}
|
}
|
||||||
@@ -370,6 +370,19 @@ public:
|
|||||||
// common code to be called on popup hide/dismiss
|
// common code to be called on popup hide/dismiss
|
||||||
void OnPopupDismiss();
|
void OnPopupDismiss();
|
||||||
|
|
||||||
|
// PopupShown states
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
Hidden = 0,
|
||||||
|
//Closing = 1,
|
||||||
|
Animating = 2,
|
||||||
|
Visible = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
bool IsPopupWindowState( int state ) const { return (state == m_popupWinState) ? true : false; }
|
||||||
|
|
||||||
|
wxByte GetPopupWindowState() const { return m_popupWinState; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -447,6 +460,23 @@ protected:
|
|||||||
// Dispatches size event and refreshes
|
// Dispatches size event and refreshes
|
||||||
void RecalcAndRefresh();
|
void RecalcAndRefresh();
|
||||||
|
|
||||||
|
// Flags for DoShowPopup and AnimateShow
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ShowBelow = 0x0000, // Showing popup below the control
|
||||||
|
ShowAbove = 0x0001, // Showing popup above the control
|
||||||
|
CanDeferShow = 0x0002 // Can only return true from AnimateShow if this is set
|
||||||
|
};
|
||||||
|
|
||||||
|
// Shows and positions the popup.
|
||||||
|
virtual void DoShowPopup( const wxRect& rect, int flags );
|
||||||
|
|
||||||
|
// Implement in derived class to create a drop-down animation.
|
||||||
|
// Return true if finished immediately. Otherwise popup is only
|
||||||
|
// shown when the derived class call DoShowPopup.
|
||||||
|
// Flags are same as for DoShowPopup.
|
||||||
|
virtual bool AnimateShow( const wxRect& rect, int flags );
|
||||||
|
|
||||||
#if wxUSE_TOOLTIPS
|
#if wxUSE_TOOLTIPS
|
||||||
virtual void DoSetToolTip( wxToolTip *tip );
|
virtual void DoSetToolTip( wxToolTip *tip );
|
||||||
#endif
|
#endif
|
||||||
@@ -540,7 +570,7 @@ protected:
|
|||||||
bool m_blankButtonBg;
|
bool m_blankButtonBg;
|
||||||
|
|
||||||
// is the popup window currenty shown?
|
// is the popup window currenty shown?
|
||||||
bool m_isPopupShown;
|
wxByte m_popupWinState;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Init();
|
void Init();
|
||||||
|
@@ -60,6 +60,7 @@ public:
|
|||||||
virtual ~wxComboCtrl();
|
virtual ~wxComboCtrl();
|
||||||
|
|
||||||
virtual void PrepareBackground( wxDC& dc, const wxRect& rect, int flags ) const;
|
virtual void PrepareBackground( wxDC& dc, const wxRect& rect, int flags ) const;
|
||||||
|
virtual bool AnimateShow( const wxRect& rect, int flags );
|
||||||
virtual bool IsKeyPopupToggle(const wxKeyEvent& event) const;
|
virtual bool IsKeyPopupToggle(const wxKeyEvent& event) const;
|
||||||
|
|
||||||
static int GetFeatures() { return wxComboCtrlFeatures::All; }
|
static int GetFeatures() { return wxComboCtrlFeatures::All; }
|
||||||
|
@@ -85,6 +85,9 @@ public:
|
|||||||
|
|
||||||
void OnIdle( wxIdleEvent& event );
|
void OnIdle( wxIdleEvent& event );
|
||||||
|
|
||||||
|
|
||||||
|
wxCheckBox* m_cbUseAnim;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
wxTextCtrl* m_logWin;
|
wxTextCtrl* m_logWin;
|
||||||
wxLog* m_logOld;
|
wxLog* m_logOld;
|
||||||
@@ -490,6 +493,66 @@ BEGIN_EVENT_TABLE(TreeCtrlComboPopup, wxTreeCtrl)
|
|||||||
EVT_LEFT_DOWN(TreeCtrlComboPopup::OnMouseClick)
|
EVT_LEFT_DOWN(TreeCtrlComboPopup::OnMouseClick)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxComboCtrl with custom popup animation
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class wxComboCtrlWithCustomPopupAnim : public wxComboCtrl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual bool AnimateShow( const wxRect& rect, int WXUNUSED(flags) )
|
||||||
|
{
|
||||||
|
MyFrame* myFrame = (MyFrame*) ::wxGetTopLevelParent(this);
|
||||||
|
|
||||||
|
if ( !myFrame->m_cbUseAnim->GetValue() )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
int width = rect.width;
|
||||||
|
int height = rect.height;
|
||||||
|
wxBitmap bitmap( width, height, -1 );
|
||||||
|
wxScreenDC dc;
|
||||||
|
wxMemoryDC memdc( bitmap );
|
||||||
|
memdc.Blit( 0, 0, width, height, &dc, rect.x, rect.y );
|
||||||
|
memdc.SelectObject(wxNullBitmap);
|
||||||
|
|
||||||
|
wxLongLong tStart = ::wxGetLocalTimeMillis();
|
||||||
|
const int delay = 300;
|
||||||
|
const int resolution = 10;
|
||||||
|
|
||||||
|
int center_x = rect.x + (width/2);
|
||||||
|
int center_y = rect.y + (height/2);
|
||||||
|
|
||||||
|
double d_height = (double) height;
|
||||||
|
|
||||||
|
dc.SetPen( *wxBLACK_PEN );
|
||||||
|
dc.SetBrush( *wxTRANSPARENT_BRUSH );
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
wxLongLong t = ::wxGetLocalTimeMillis();
|
||||||
|
int pos = (int) (t-tStart).GetLo();
|
||||||
|
if ( pos > delay )
|
||||||
|
break;
|
||||||
|
|
||||||
|
int w = (((pos*256)/delay)*width)/256;
|
||||||
|
|
||||||
|
double ratio = ((double)w / (double)width);
|
||||||
|
int h = (int)(d_height * ratio);
|
||||||
|
dc.DrawRectangle( center_x - w/2, center_y - h/2, w, h );
|
||||||
|
wxMilliSleep( resolution );
|
||||||
|
wxYield();
|
||||||
|
dc.DrawBitmap( bitmap, rect.x, rect.y );
|
||||||
|
|
||||||
|
if ( IsPopupWindowState(Hidden) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxComboCtrl with entirely custom button action (opens file dialog)
|
// wxComboCtrl with entirely custom button action (opens file dialog)
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -730,8 +793,8 @@ MyFrame::MyFrame(const wxString& title)
|
|||||||
colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
|
colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
|
||||||
|
|
||||||
rowSizer = new wxBoxSizer( wxHORIZONTAL );
|
rowSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||||
cc = new wxComboCtrl(panel,2,wxEmptyString,
|
cc = new wxComboCtrlWithCustomPopupAnim();
|
||||||
wxDefaultPosition, wxDefaultSize);
|
cc->Create(panel, wxID_ANY, wxEmptyString);
|
||||||
|
|
||||||
// Make sure we use popup that allows focusing the listview.
|
// Make sure we use popup that allows focusing the listview.
|
||||||
cc->UseAltPopupWindow();
|
cc->UseAltPopupWindow();
|
||||||
@@ -879,7 +942,23 @@ MyFrame::MyFrame(const wxString& title)
|
|||||||
|
|
||||||
topRowSizer->Add( colSizer, 1, wxALL, 2 );
|
topRowSizer->Add( colSizer, 1, wxALL, 2 );
|
||||||
|
|
||||||
topRowSizer->Add( m_logWin, 1, wxEXPAND|wxALL, 5 );
|
colSizer = new wxBoxSizer( wxVERTICAL );
|
||||||
|
|
||||||
|
wxStaticBoxSizer* sbSizer = new wxStaticBoxSizer( new wxStaticBox(panel,
|
||||||
|
wxID_ANY,
|
||||||
|
wxT("Options")),
|
||||||
|
wxVERTICAL );
|
||||||
|
|
||||||
|
m_cbUseAnim = new wxCheckBox(panel, wxID_ANY, wxT("Custom popup animation for ListView wxComboCtrl"));
|
||||||
|
m_cbUseAnim->SetValue(true);
|
||||||
|
sbSizer->Add( m_cbUseAnim, 0, wxALL, 3 );
|
||||||
|
|
||||||
|
colSizer->Add( sbSizer, 0, wxEXPAND|wxALL, 3 );
|
||||||
|
colSizer->AddSpacer(8);
|
||||||
|
colSizer->Add( new wxStaticText(panel, wxID_ANY, wxT("Log Messages:")), 0, wxTOP|wxLEFT, 3 );
|
||||||
|
colSizer->Add( m_logWin, 1, wxEXPAND|wxALL, 3 );
|
||||||
|
|
||||||
|
topRowSizer->Add( colSizer, 1, wxEXPAND|wxALL, 2 );
|
||||||
topSizer->Add( topRowSizer, 1, wxEXPAND );
|
topSizer->Add( topRowSizer, 1, wxEXPAND );
|
||||||
|
|
||||||
panel->SetSizer( topSizer );
|
panel->SetSizer( topSizer );
|
||||||
|
@@ -44,10 +44,6 @@
|
|||||||
// constants
|
// constants
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Milliseconds to wait for two mouse-ups after focus inorder
|
|
||||||
// to trigger a double-click.
|
|
||||||
#define DOUBLE_CLICK_CONVERSION_TRESHOLD 500
|
|
||||||
|
|
||||||
#define DEFAULT_DROPBUTTON_WIDTH 19
|
#define DEFAULT_DROPBUTTON_WIDTH 19
|
||||||
|
|
||||||
#define BMP_BUTTON_MARGIN 4
|
#define BMP_BUTTON_MARGIN 4
|
||||||
@@ -344,20 +340,50 @@ public:
|
|||||||
style)
|
style)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
m_inShow = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USES_WXPOPUPTRANSIENTWINDOW
|
#if USES_WXPOPUPTRANSIENTWINDOW
|
||||||
|
virtual bool Show( bool show );
|
||||||
virtual bool ProcessLeftDown(wxMouseEvent& event);
|
virtual bool ProcessLeftDown(wxMouseEvent& event);
|
||||||
virtual void OnDismiss();
|
virtual void OnDismiss();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxByte m_inShow;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#if USES_WXPOPUPTRANSIENTWINDOW
|
#if USES_WXPOPUPTRANSIENTWINDOW
|
||||||
bool wxComboPopupWindow::ProcessLeftDown(wxMouseEvent& event )
|
bool wxComboPopupWindow::Show( bool show )
|
||||||
{
|
{
|
||||||
return wxComboPopupWindowBase::ProcessLeftDown(event);
|
// Guard against recursion
|
||||||
|
if ( m_inShow )
|
||||||
|
return wxComboPopupWindowBase::Show(show);
|
||||||
|
|
||||||
|
m_inShow++;
|
||||||
|
|
||||||
|
wxASSERT( IsKindOf(CLASSINFO(wxPopupTransientWindow)) );
|
||||||
|
|
||||||
|
wxPopupTransientWindow* ptw = (wxPopupTransientWindow*) this;
|
||||||
|
wxComboCtrlBase* combo = (wxComboCtrlBase*) GetParent();
|
||||||
|
|
||||||
|
if ( show != ptw->IsShown() )
|
||||||
|
{
|
||||||
|
if ( show )
|
||||||
|
ptw->Popup(combo->GetPopupControl()->GetControl());
|
||||||
|
else
|
||||||
|
ptw->Dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_inShow--;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxComboPopupWindow::ProcessLeftDown(wxMouseEvent& event)
|
||||||
|
{
|
||||||
|
return wxPopupTransientWindow::ProcessLeftDown(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
@@ -387,6 +413,7 @@ public:
|
|||||||
m_combo = parent;
|
m_combo = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnSizeEvent( wxSizeEvent& event );
|
||||||
void OnKeyEvent(wxKeyEvent& event);
|
void OnKeyEvent(wxKeyEvent& event);
|
||||||
#if USES_WXDIALOG
|
#if USES_WXDIALOG
|
||||||
void OnActivate( wxActivateEvent& event );
|
void OnActivate( wxActivateEvent& event );
|
||||||
@@ -405,9 +432,15 @@ BEGIN_EVENT_TABLE(wxComboPopupWindowEvtHandler, wxEvtHandler)
|
|||||||
#if USES_WXDIALOG
|
#if USES_WXDIALOG
|
||||||
EVT_ACTIVATE(wxComboPopupWindowEvtHandler::OnActivate)
|
EVT_ACTIVATE(wxComboPopupWindowEvtHandler::OnActivate)
|
||||||
#endif
|
#endif
|
||||||
|
EVT_SIZE(wxComboPopupWindowEvtHandler::OnSizeEvent)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
void wxComboPopupWindowEvtHandler::OnSizeEvent( wxSizeEvent& WXUNUSED(event) )
|
||||||
|
{
|
||||||
|
// Block the event so that the popup control does not get auto-resized.
|
||||||
|
}
|
||||||
|
|
||||||
void wxComboPopupWindowEvtHandler::OnKeyEvent( wxKeyEvent& event )
|
void wxComboPopupWindowEvtHandler::OnKeyEvent( wxKeyEvent& event )
|
||||||
{
|
{
|
||||||
// Relay keyboard event to the main child controls
|
// Relay keyboard event to the main child controls
|
||||||
@@ -621,7 +654,7 @@ void wxComboPopupExtraEventHandler::OnMouseEvent( wxMouseEvent& event )
|
|||||||
evtType == wxEVT_RIGHT_DOWN )
|
evtType == wxEVT_RIGHT_DOWN )
|
||||||
{
|
{
|
||||||
// Block motion and click events outside the popup
|
// Block motion and click events outside the popup
|
||||||
if ( !isInside )
|
if ( !isInside || !m_combo->IsPopupShown() )
|
||||||
{
|
{
|
||||||
event.Skip(false);
|
event.Skip(false);
|
||||||
return;
|
return;
|
||||||
@@ -629,11 +662,10 @@ void wxComboPopupExtraEventHandler::OnMouseEvent( wxMouseEvent& event )
|
|||||||
}
|
}
|
||||||
else if ( evtType == wxEVT_LEFT_UP )
|
else if ( evtType == wxEVT_LEFT_UP )
|
||||||
{
|
{
|
||||||
// Don't let left-down events in if outside
|
if ( !m_combo->IsPopupShown() )
|
||||||
if ( evtType == wxEVT_LEFT_DOWN )
|
|
||||||
{
|
{
|
||||||
if ( !isInside )
|
event.Skip(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !m_beenInside )
|
if ( !m_beenInside )
|
||||||
@@ -688,7 +720,7 @@ void wxComboCtrlBase::Init()
|
|||||||
{
|
{
|
||||||
m_winPopup = (wxWindow *)NULL;
|
m_winPopup = (wxWindow *)NULL;
|
||||||
m_popup = (wxWindow *)NULL;
|
m_popup = (wxWindow *)NULL;
|
||||||
m_isPopupShown = false;
|
m_popupWinState = Hidden;
|
||||||
m_btn = (wxWindow*) NULL;
|
m_btn = (wxWindow*) NULL;
|
||||||
m_text = (wxTextCtrl*) NULL;
|
m_text = (wxTextCtrl*) NULL;
|
||||||
m_popupInterface = (wxComboPopup*) NULL;
|
m_popupInterface = (wxComboPopup*) NULL;
|
||||||
@@ -1212,7 +1244,7 @@ void wxComboCtrlBase::DrawButton( wxDC& dc, const wxRect& rect, bool paintBg )
|
|||||||
int drawState = m_btnState;
|
int drawState = m_btnState;
|
||||||
|
|
||||||
#ifdef __WXGTK__
|
#ifdef __WXGTK__
|
||||||
if ( m_isPopupShown )
|
if ( GetPopupWindowState() >= Animating )
|
||||||
drawState |= wxCONTROL_PRESSED;
|
drawState |= wxCONTROL_PRESSED;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1365,7 +1397,7 @@ bool wxComboCtrlBase::HandleButtonMouseEvent( wxMouseEvent& event,
|
|||||||
Refresh();
|
Refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( type == wxEVT_LEFT_DOWN )
|
else if ( type == wxEVT_LEFT_DOWN || type == wxEVT_LEFT_DCLICK )
|
||||||
{
|
{
|
||||||
if ( flags & (wxCC_MF_ON_CLICK_AREA|wxCC_MF_ON_BUTTON) )
|
if ( flags & (wxCC_MF_ON_CLICK_AREA|wxCC_MF_ON_BUTTON) )
|
||||||
{
|
{
|
||||||
@@ -1406,7 +1438,7 @@ bool wxComboCtrlBase::HandleButtonMouseEvent( wxMouseEvent& event,
|
|||||||
m_btnState &= ~(wxCONTROL_CURRENT);
|
m_btnState &= ~(wxCONTROL_CURRENT);
|
||||||
|
|
||||||
// Mouse hover ends
|
// Mouse hover ends
|
||||||
if ( !m_isPopupShown )
|
if ( IsPopupWindowState(Hidden) )
|
||||||
{
|
{
|
||||||
m_btnState &= ~(wxCONTROL_PRESSED);
|
m_btnState &= ~(wxCONTROL_PRESSED);
|
||||||
Refresh();
|
Refresh();
|
||||||
@@ -1429,7 +1461,7 @@ bool wxComboCtrlBase::PreprocessMouseEvent( wxMouseEvent& event,
|
|||||||
#if USES_WXPOPUPWINDOW || USES_WXDIALOG
|
#if USES_WXPOPUPWINDOW || USES_WXDIALOG
|
||||||
if ( m_popupWinType != POPUPWIN_WXPOPUPTRANSIENTWINDOW )
|
if ( m_popupWinType != POPUPWIN_WXPOPUPTRANSIENTWINDOW )
|
||||||
{
|
{
|
||||||
if ( m_isPopupShown &&
|
if ( IsPopupWindowState(Visible) &&
|
||||||
( evtType == wxEVT_LEFT_DOWN || evtType == wxEVT_RIGHT_DOWN ) )
|
( evtType == wxEVT_LEFT_DOWN || evtType == wxEVT_RIGHT_DOWN ) )
|
||||||
{
|
{
|
||||||
HidePopup();
|
HidePopup();
|
||||||
@@ -1455,7 +1487,7 @@ void wxComboCtrlBase::HandleNormalMouseEvent( wxMouseEvent& event )
|
|||||||
if ( (evtType == wxEVT_LEFT_DOWN || evtType == wxEVT_LEFT_DCLICK) &&
|
if ( (evtType == wxEVT_LEFT_DOWN || evtType == wxEVT_LEFT_DCLICK) &&
|
||||||
(m_windowStyle & wxCB_READONLY) )
|
(m_windowStyle & wxCB_READONLY) )
|
||||||
{
|
{
|
||||||
if ( m_isPopupShown )
|
if ( GetPopupWindowState() >= Animating )
|
||||||
{
|
{
|
||||||
#if USES_WXPOPUPWINDOW
|
#if USES_WXPOPUPWINDOW
|
||||||
// Click here always hides the popup.
|
// Click here always hides the popup.
|
||||||
@@ -1481,7 +1513,7 @@ void wxComboCtrlBase::HandleNormalMouseEvent( wxMouseEvent& event )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if ( m_isPopupShown )
|
if ( IsPopupShown() )
|
||||||
{
|
{
|
||||||
// relay (some) mouse events to the popup
|
// relay (some) mouse events to the popup
|
||||||
if ( evtType == wxEVT_MOUSEWHEEL )
|
if ( evtType == wxEVT_MOUSEWHEEL )
|
||||||
@@ -1677,7 +1709,10 @@ void wxComboCtrlBase::OnButtonClick()
|
|||||||
void wxComboCtrlBase::ShowPopup()
|
void wxComboCtrlBase::ShowPopup()
|
||||||
{
|
{
|
||||||
EnsurePopupControl();
|
EnsurePopupControl();
|
||||||
wxCHECK_RET( !IsPopupShown(), wxT("popup window already shown") );
|
wxCHECK_RET( !IsPopupWindowState(Visible), wxT("popup window already shown") );
|
||||||
|
|
||||||
|
if ( IsPopupWindowState(Animating) )
|
||||||
|
return;
|
||||||
|
|
||||||
SetFocus();
|
SetFocus();
|
||||||
|
|
||||||
@@ -1793,22 +1828,27 @@ void wxComboCtrlBase::ShowPopup()
|
|||||||
else
|
else
|
||||||
popupX = 0;
|
popupX = 0;
|
||||||
|
|
||||||
|
int showFlags = CanDeferShow;
|
||||||
|
|
||||||
if ( spaceBelow < szp.y )
|
if ( spaceBelow < szp.y )
|
||||||
{
|
{
|
||||||
popupY = scrPos.y - szp.y;
|
popupY = scrPos.y - szp.y;
|
||||||
|
showFlags |= ShowAbove;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move to position
|
#if INSTALL_TOPLEV_HANDLER
|
||||||
//wxLogDebug(wxT("popup scheduled position1: %i,%i"),ptp.x,ptp.y);
|
// Put top level window event handler into place
|
||||||
//wxLogDebug(wxT("popup position1: %i,%i"),winPopup->GetPosition().x,winPopup->GetPosition().y);
|
if ( m_popupWinType == POPUPWIN_WXPOPUPWINDOW )
|
||||||
|
{
|
||||||
|
if ( !m_toplevEvtHandler )
|
||||||
|
m_toplevEvtHandler = new wxComboFrameEventHandler(this);
|
||||||
|
|
||||||
// Some platforms (GTK) may need these two to be separate
|
wxWindow* toplev = ::wxGetTopLevelParent( this );
|
||||||
winPopup->SetSize( szp.x, szp.y );
|
wxASSERT( toplev );
|
||||||
winPopup->Move( popupX, popupY );
|
((wxComboFrameEventHandler*)m_toplevEvtHandler)->OnPopup();
|
||||||
|
toplev->PushEventHandler( m_toplevEvtHandler );
|
||||||
//wxLogDebug(wxT("popup position2: %i,%i"),winPopup->GetPosition().x,winPopup->GetPosition().y);
|
}
|
||||||
|
#endif
|
||||||
m_popup = popup;
|
|
||||||
|
|
||||||
// Set string selection (must be this way instead of SetStringSelection)
|
// Set string selection (must be this way instead of SetStringSelection)
|
||||||
if ( m_text )
|
if ( m_text )
|
||||||
@@ -1825,51 +1865,68 @@ void wxComboCtrlBase::ShowPopup()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This must be after SetStringValue
|
// This must be after SetStringValue
|
||||||
m_isPopupShown = true;
|
m_popupWinState = Animating;
|
||||||
|
|
||||||
|
wxRect popupWinRect( popupX, popupY, szp.x, szp.y );
|
||||||
|
|
||||||
|
m_popup = popup;
|
||||||
|
if ( AnimateShow( popupWinRect, showFlags ) )
|
||||||
|
{
|
||||||
|
DoShowPopup( popupWinRect, showFlags );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxComboCtrlBase::AnimateShow( const wxRect& WXUNUSED(rect), int WXUNUSED(flags) )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxComboCtrlBase::DoShowPopup( const wxRect& rect, int WXUNUSED(flags) )
|
||||||
|
{
|
||||||
|
wxWindow* winPopup = m_winPopup;
|
||||||
|
|
||||||
|
if ( IsPopupWindowState(Animating) )
|
||||||
|
{
|
||||||
|
// Make sure the popup window is shown in the right position.
|
||||||
|
// Should not matter even if animation already did this.
|
||||||
|
|
||||||
|
// Some platforms (GTK) may like SetSize and Move to be separate
|
||||||
|
// (though the bug was probably fixed).
|
||||||
|
winPopup->SetSize( rect );
|
||||||
|
|
||||||
// Show it
|
|
||||||
#if USES_WXPOPUPTRANSIENTWINDOW
|
|
||||||
if ( m_popupWinType == POPUPWIN_WXPOPUPTRANSIENTWINDOW )
|
|
||||||
((wxPopupTransientWindow*)winPopup)->Popup(popup);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
winPopup->Show();
|
winPopup->Show();
|
||||||
|
|
||||||
#if INSTALL_TOPLEV_HANDLER
|
m_popupWinState = Visible;
|
||||||
// Put top level window event handler into place
|
|
||||||
if ( m_popupWinType == POPUPWIN_WXPOPUPWINDOW )
|
|
||||||
{
|
|
||||||
if ( !m_toplevEvtHandler )
|
|
||||||
m_toplevEvtHandler = new wxComboFrameEventHandler(this);
|
|
||||||
|
|
||||||
wxWindow* toplev = ::wxGetTopLevelParent( this );
|
|
||||||
wxASSERT( toplev );
|
|
||||||
((wxComboFrameEventHandler*)m_toplevEvtHandler)->OnPopup();
|
|
||||||
toplev->PushEventHandler( m_toplevEvtHandler );
|
|
||||||
}
|
}
|
||||||
#endif
|
else if ( IsPopupWindowState(Hidden) )
|
||||||
|
{
|
||||||
|
// Animation was aborted
|
||||||
|
|
||||||
|
wxASSERT( !winPopup->IsShown() );
|
||||||
|
|
||||||
|
m_popupWinState = Hidden;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxComboCtrlBase::OnPopupDismiss()
|
void wxComboCtrlBase::OnPopupDismiss()
|
||||||
{
|
{
|
||||||
// Just in case, avoid double dismiss
|
// Just in case, avoid double dismiss
|
||||||
if ( !m_isPopupShown )
|
if ( IsPopupWindowState(Hidden) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// NB: Focus setting is really funny, atleast on wxMSW. First of all,
|
// NB: Focus setting is really funny, atleast on wxMSW. First of all,
|
||||||
// we need to have SetFocus at the end. Otherwise wxTextCtrl may
|
// we need to have SetFocus at the end. Otherwise wxTextCtrl may
|
||||||
// freeze until focus goes somewhere else. Second, wxTreeCtrl as
|
// freeze until focus goes somewhere else. Second, wxTreeCtrl as
|
||||||
// popup, when dismissing, "steals" focus back to itself unless
|
// popup, when dismissing, "steals" focus back to itself unless
|
||||||
// SetFocus is called also here, exactly before m_isPopupShown
|
// SetFocus is called also here, exactly before m_popupWinState
|
||||||
// is set to false. Which is truly weird since SetFocus is just
|
// is set to false. Which is truly weird since SetFocus is just
|
||||||
// wxWindowMSW method and does not call event handler or anything like
|
// wxWindowMSW method and does not call event handler or anything like
|
||||||
// that (ie. does not care about m_isPopupShown).
|
// that (ie. does not care about m_popupWinState).
|
||||||
|
|
||||||
SetFocus();
|
SetFocus();
|
||||||
|
|
||||||
// This should preferably be set before focus.
|
// This should preferably be set before focus.
|
||||||
m_isPopupShown = false;
|
m_popupWinState = Hidden;
|
||||||
|
|
||||||
// Inform popup control itself
|
// Inform popup control itself
|
||||||
m_popupInterface->OnDismiss();
|
m_popupInterface->OnDismiss();
|
||||||
@@ -1887,7 +1944,10 @@ void wxComboCtrlBase::OnPopupDismiss()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_timeCanAcceptClick = ::wxGetLocalTimeMillis() + 150;
|
m_timeCanAcceptClick = ::wxGetLocalTimeMillis();
|
||||||
|
|
||||||
|
if ( m_popupWinType == POPUPWIN_WXPOPUPTRANSIENTWINDOW )
|
||||||
|
m_timeCanAcceptClick += 150;
|
||||||
|
|
||||||
// If cursor not on dropdown button, then clear its state
|
// If cursor not on dropdown button, then clear its state
|
||||||
// (technically not required by all ports, but do it for all just in case)
|
// (technically not required by all ports, but do it for all just in case)
|
||||||
@@ -1912,19 +1972,14 @@ void wxComboCtrlBase::OnPopupDismiss()
|
|||||||
void wxComboCtrlBase::HidePopup()
|
void wxComboCtrlBase::HidePopup()
|
||||||
{
|
{
|
||||||
// Should be able to call this without popup interface
|
// Should be able to call this without popup interface
|
||||||
//wxCHECK_RET( m_popupInterface, _T("no popup interface") );
|
if ( IsPopupWindowState(Hidden) )
|
||||||
if ( !m_isPopupShown )
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// transfer value and show it in textctrl, if any
|
// transfer value and show it in textctrl, if any
|
||||||
SetValue( m_popupInterface->GetStringValue() );
|
if ( !IsPopupWindowState(Animating) )
|
||||||
|
SetValue( m_popupInterface->GetStringValue() );
|
||||||
|
|
||||||
#if USES_WXPOPUPTRANSIENTWINDOW
|
m_winPopup->Hide();
|
||||||
if ( m_popupWinType == POPUPWIN_WXPOPUPTRANSIENTWINDOW )
|
|
||||||
((wxPopupTransientWindow*)m_winPopup)->Dismiss();
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
m_winPopup->Hide();
|
|
||||||
|
|
||||||
OnPopupDismiss();
|
OnPopupDismiss();
|
||||||
}
|
}
|
||||||
|
@@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
#include "wx/combo.h"
|
#include "wx/combo.h"
|
||||||
|
|
||||||
|
#include "wx/msw/registry.h"
|
||||||
#include "wx/msw/uxtheme.h"
|
#include "wx/msw/uxtheme.h"
|
||||||
|
|
||||||
// Change to #if 1 to include tmschema.h for easier testing of theme
|
// Change to #if 1 to include tmschema.h for easier testing of theme
|
||||||
@@ -70,6 +70,7 @@
|
|||||||
#define TEXTCTRLXADJUST_CLASSIC 1
|
#define TEXTCTRLXADJUST_CLASSIC 1
|
||||||
#define TEXTCTRLYADJUST_CLASSIC 2
|
#define TEXTCTRLYADJUST_CLASSIC 2
|
||||||
|
|
||||||
|
#define COMBOBOX_ANIMATION_DURATION 200 // In milliseconds
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// implementation
|
// implementation
|
||||||
@@ -529,6 +530,94 @@ void wxComboCtrl::OnMouseEvent( wxMouseEvent& event )
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(__WXWINCE__)
|
||||||
|
static wxUint32 GetUserPreferencesMask()
|
||||||
|
{
|
||||||
|
static wxUint32 userPreferencesMask = 0;
|
||||||
|
static bool valueSet = false;
|
||||||
|
|
||||||
|
if ( valueSet )
|
||||||
|
return userPreferencesMask;
|
||||||
|
|
||||||
|
wxRegKey key(wxRegKey::HKCU, wxT("Control Panel\\Desktop"));
|
||||||
|
if( key.Open(wxRegKey::Read) )
|
||||||
|
{
|
||||||
|
wxMemoryBuffer buf;
|
||||||
|
if ( key.QueryValue(wxT("UserPreferencesMask"), buf) )
|
||||||
|
{
|
||||||
|
if ( buf.GetDataLen() >= 4 )
|
||||||
|
{
|
||||||
|
wxByte* p = (wxByte*) buf.GetData();
|
||||||
|
userPreferencesMask = p[3] + (p[2]<<8) + (p[1]<<16) + (p[0]<<24);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
valueSet = true;
|
||||||
|
|
||||||
|
return userPreferencesMask;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool wxComboCtrl::AnimateShow( const wxRect& rect, int flags )
|
||||||
|
{
|
||||||
|
#if !defined(__WXWINCE__)
|
||||||
|
if ( GetUserPreferencesMask() & (1<<26) )
|
||||||
|
{
|
||||||
|
wxLongLong tStart = ::wxGetLocalTimeMillis();
|
||||||
|
|
||||||
|
int height = rect.height;
|
||||||
|
|
||||||
|
wxWindow* win = GetPopupWindow();
|
||||||
|
wxWindow* popup = GetPopupControl()->GetControl();
|
||||||
|
|
||||||
|
const int delay = COMBOBOX_ANIMATION_DURATION;
|
||||||
|
const int resolution = 10;
|
||||||
|
int h0 = popup->GetSize().y;
|
||||||
|
|
||||||
|
win->SetSize( rect.x, rect.y, rect.width, 0 );
|
||||||
|
win->Show();
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
wxLongLong t = ::wxGetLocalTimeMillis();
|
||||||
|
int pos = (int) (t-tStart).GetLo();
|
||||||
|
if ( pos > delay )
|
||||||
|
break;
|
||||||
|
|
||||||
|
int h = (((pos*256)/delay)*height)/256;
|
||||||
|
int y = (h0 - h);
|
||||||
|
if ( y < 0 )
|
||||||
|
y = 0;
|
||||||
|
|
||||||
|
if ( flags & ShowAbove )
|
||||||
|
{
|
||||||
|
win->SetSize( rect.x, rect.y + h0 - h, rect.width, h );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
popup->Move( 0, -y );
|
||||||
|
win->SetSize( rect.x, rect.y, rect.width, h );
|
||||||
|
}
|
||||||
|
|
||||||
|
wxMilliSleep( resolution );
|
||||||
|
wxYield();
|
||||||
|
|
||||||
|
// Popup was hidden before it was fully shown?
|
||||||
|
if ( IsPopupWindowState(Hidden) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
popup->Move( 0, 0 );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
wxUnusedVar(rect);
|
||||||
|
wxUnusedVar(flags);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
wxCoord wxComboCtrl::GetNativeTextIndent() const
|
wxCoord wxComboCtrl::GetNativeTextIndent() const
|
||||||
{
|
{
|
||||||
if ( wxUxThemeEngine::GetIfActive() )
|
if ( wxUxThemeEngine::GetIfActive() )
|
||||||
|
Reference in New Issue
Block a user