Make animation of combo-popdown optional.
Replace wxMiniSleep() + wxYield() implemenation by wxTimer based one. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@42470 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -295,6 +295,14 @@ In this case, \helpref{AnimateShow}{wxcomboctrlanimateshow} must return \false.}
|
|||||||
\end{twocollist}
|
\end{twocollist}
|
||||||
|
|
||||||
|
|
||||||
|
\membersection{wxComboCtrl::EnablePopupAnimation}\label{wxcomboctrlenablepopupanimation}
|
||||||
|
|
||||||
|
\func{void}{EnablePopupAnimation}{\param{bool }{enable = true}}
|
||||||
|
|
||||||
|
Enables or disables popup animation, if any, depending on the value of
|
||||||
|
the argument.
|
||||||
|
|
||||||
|
|
||||||
\membersection{wxComboCtrl::GetBitmapDisabled}\label{wxcomboctrlgetbitmapdisabled}
|
\membersection{wxComboCtrl::GetBitmapDisabled}\label{wxcomboctrlgetbitmapdisabled}
|
||||||
|
|
||||||
\constfunc{const wxBitmap\&}{GetBitmapDisabled}{\void}
|
\constfunc{const wxBitmap\&}{GetBitmapDisabled}{\void}
|
||||||
|
@@ -85,7 +85,9 @@ enum
|
|||||||
// 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).
|
// Internal use: Secondary popup window type should be used (if available).
|
||||||
wxCC_IFLAG_USE_ALT_POPUP = 0x1000
|
wxCC_IFLAG_USE_ALT_POPUP = 0x1000,
|
||||||
|
// Internal use: Skip popup animation.
|
||||||
|
wxCC_IFLAG_DISABLE_POPUP_ANIM = 0x2000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -322,6 +324,15 @@ public:
|
|||||||
m_iFlags &= ~wxCC_IFLAG_USE_ALT_POPUP;
|
m_iFlags &= ~wxCC_IFLAG_USE_ALT_POPUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Call with false to disable popup animation, if any.
|
||||||
|
void EnablePopupAnimation( bool enable = true )
|
||||||
|
{
|
||||||
|
if ( enable )
|
||||||
|
m_iFlags &= ~wxCC_IFLAG_DISABLE_POPUP_ANIM;
|
||||||
|
else
|
||||||
|
m_iFlags |= wxCC_IFLAG_DISABLE_POPUP_ANIM;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Utilies needed by the popups or native implementations
|
// Utilies needed by the popups or native implementations
|
||||||
//
|
//
|
||||||
|
@@ -18,6 +18,14 @@
|
|||||||
|
|
||||||
#if wxUSE_COMBOCTRL
|
#if wxUSE_COMBOCTRL
|
||||||
|
|
||||||
|
#if !defined(__WXWINCE__) && wxUSE_TIMER
|
||||||
|
#include "wx/timer.h"
|
||||||
|
#define wxUSE_COMBOCTRL_POPUP_ANIMATION 1
|
||||||
|
#else
|
||||||
|
#define wxUSE_COMBOCTRL_POPUP_ANIMATION 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Native wxComboCtrl
|
// Native wxComboCtrl
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -60,11 +68,15 @@ 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; }
|
||||||
|
|
||||||
|
#if wxUSE_COMBOCTRL_POPUP_ANIMATION
|
||||||
|
virtual bool AnimateShow( const wxRect& rect, int flags );
|
||||||
|
void OnTimerEvent( wxTimerEvent& event );
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// customization
|
// customization
|
||||||
@@ -79,6 +91,14 @@ protected:
|
|||||||
private:
|
private:
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
|
#if wxUSE_COMBOCTRL_POPUP_ANIMATION
|
||||||
|
// Popup animation related
|
||||||
|
wxLongLong m_animStart;
|
||||||
|
wxTimer m_animTimer;
|
||||||
|
wxRect m_animRect;
|
||||||
|
int m_animFlags;
|
||||||
|
#endif
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
|
|
||||||
DECLARE_DYNAMIC_CLASS(wxComboCtrl)
|
DECLARE_DYNAMIC_CLASS(wxComboCtrl)
|
||||||
|
@@ -494,31 +494,72 @@ BEGIN_EVENT_TABLE(TreeCtrlComboPopup, wxTreeCtrl)
|
|||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxComboCtrl with custom popup animation
|
// wxComboCtrl with custom popup animation. We use EVT_TIMER, which is quite
|
||||||
|
// safe, but requires much more can than doing it in a single function (ie.
|
||||||
|
// AnimateShow) and using combination of wxSleep and wxSafeYield.
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if wxUSE_TIMER
|
||||||
|
|
||||||
|
#define CUSTOM_COMBOBOX_ANIMATION_DURATION 200 // In milliseconds
|
||||||
|
|
||||||
|
#include "wx/timer.h"
|
||||||
|
|
||||||
class wxComboCtrlWithCustomPopupAnim : public wxComboCtrl
|
class wxComboCtrlWithCustomPopupAnim : public wxComboCtrl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual bool AnimateShow( const wxRect& rect, int WXUNUSED(flags) )
|
virtual bool AnimateShow( const wxRect& rect, int flags )
|
||||||
{
|
{
|
||||||
MyFrame* myFrame = (MyFrame*) ::wxGetTopLevelParent(this);
|
MyFrame* myFrame = (MyFrame*) ::wxGetTopLevelParent(this);
|
||||||
|
|
||||||
if ( !myFrame->m_cbUseAnim->GetValue() )
|
if ( !myFrame->m_cbUseAnim->GetValue() )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
m_animStart = ::wxGetLocalTimeMillis();
|
||||||
|
m_animRect = rect;
|
||||||
|
m_animFlags = flags;
|
||||||
|
|
||||||
|
wxScreenDC dc;
|
||||||
|
|
||||||
|
wxBitmap bitmap( rect.width, rect.height, -1 );
|
||||||
|
wxMemoryDC memdc( bitmap );
|
||||||
|
memdc.Blit( 0, 0, rect.width, rect.height, &dc, rect.x, rect.y );
|
||||||
|
memdc.SelectObject(wxNullBitmap);
|
||||||
|
m_animBackBitmap = bitmap;
|
||||||
|
|
||||||
|
m_animTimer.SetOwner( this, wxID_ANY );
|
||||||
|
m_animTimer.Start( 10, wxTIMER_CONTINUOUS );
|
||||||
|
|
||||||
|
OnTimerEvent(*((wxTimerEvent*)NULL)); // Event is never used, so we can give NULL
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnTimerEvent( wxTimerEvent& WXUNUSED(event) )
|
||||||
|
{
|
||||||
|
bool stopTimer = false;
|
||||||
|
|
||||||
|
wxWindow* popup = GetPopupControl()->GetControl();
|
||||||
|
wxScreenDC dc;
|
||||||
|
const wxRect& rect = m_animRect;
|
||||||
|
|
||||||
|
// Popup was hidden before it was fully shown?
|
||||||
|
if ( IsPopupWindowState(Hidden) )
|
||||||
|
{
|
||||||
|
stopTimer = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxLongLong t = ::wxGetLocalTimeMillis();
|
||||||
|
|
||||||
|
int pos = (int) (t-m_animStart).GetLo();
|
||||||
|
if ( pos < CUSTOM_COMBOBOX_ANIMATION_DURATION )
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Actual animation happens here
|
||||||
|
//
|
||||||
int width = rect.width;
|
int width = rect.width;
|
||||||
int height = rect.height;
|
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_x = rect.x + (width/2);
|
||||||
int center_y = rect.y + (height/2);
|
int center_y = rect.y + (height/2);
|
||||||
@@ -527,32 +568,52 @@ public:
|
|||||||
|
|
||||||
dc.SetPen( *wxBLACK_PEN );
|
dc.SetPen( *wxBLACK_PEN );
|
||||||
dc.SetBrush( *wxTRANSPARENT_BRUSH );
|
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;
|
int w = (((pos*256)/CUSTOM_COMBOBOX_ANIMATION_DURATION)*width)/256;
|
||||||
|
|
||||||
double ratio = ((double)w / (double)width);
|
double ratio = ((double)w / (double)width);
|
||||||
int h = (int)(d_height * ratio);
|
int h = (int)(d_height * ratio);
|
||||||
|
dc.DrawBitmap( m_animBackBitmap, rect.x, rect.y );
|
||||||
dc.DrawRectangle( center_x - w/2, center_y - h/2, w, h );
|
dc.DrawRectangle( center_x - w/2, center_y - h/2, w, h );
|
||||||
wxMilliSleep( resolution );
|
}
|
||||||
wxYield();
|
else
|
||||||
dc.DrawBitmap( bitmap, rect.x, rect.y );
|
{
|
||||||
|
stopTimer = true;
|
||||||
if ( IsPopupWindowState(Hidden) )
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
if ( stopTimer )
|
||||||
|
{
|
||||||
|
dc.DrawBitmap( m_animBackBitmap, rect.x, rect.y );
|
||||||
|
popup->Move( 0, 0 );
|
||||||
|
m_animTimer.Stop();
|
||||||
|
DoShowPopup( m_animRect, m_animFlags );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
// Popup animation related
|
||||||
|
wxLongLong m_animStart;
|
||||||
|
wxTimer m_animTimer;
|
||||||
|
wxRect m_animRect;
|
||||||
|
wxBitmap m_animBackBitmap;
|
||||||
|
int m_animFlags;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BEGIN_EVENT_TABLE(wxComboCtrlWithCustomPopupAnim, wxComboCtrl)
|
||||||
|
EVT_TIMER(wxID_ANY, wxComboCtrlWithCustomPopupAnim::OnTimerEvent)
|
||||||
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define wxComboCtrlWithCustomPopupAnim wxComboCtrl
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxComboCtrl with entirely custom button action (opens file dialog)
|
// wxComboCtrl with entirely custom button action (opens file dialog)
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -1870,7 +1870,8 @@ void wxComboCtrlBase::ShowPopup()
|
|||||||
wxRect popupWinRect( popupX, popupY, szp.x, szp.y );
|
wxRect popupWinRect( popupX, popupY, szp.x, szp.y );
|
||||||
|
|
||||||
m_popup = popup;
|
m_popup = popup;
|
||||||
if ( AnimateShow( popupWinRect, showFlags ) )
|
if ( (m_iFlags & wxCC_IFLAG_DISABLE_POPUP_ANIM) ||
|
||||||
|
AnimateShow( popupWinRect, showFlags ) )
|
||||||
{
|
{
|
||||||
DoShowPopup( popupWinRect, showFlags );
|
DoShowPopup( popupWinRect, showFlags );
|
||||||
}
|
}
|
||||||
|
@@ -70,8 +70,13 @@
|
|||||||
#define TEXTCTRLXADJUST_CLASSIC 1
|
#define TEXTCTRLXADJUST_CLASSIC 1
|
||||||
#define TEXTCTRLYADJUST_CLASSIC 2
|
#define TEXTCTRLYADJUST_CLASSIC 2
|
||||||
|
|
||||||
|
#define COMBOBOX_ANIMATION_RESOLUTION 10
|
||||||
|
|
||||||
#define COMBOBOX_ANIMATION_DURATION 200 // In milliseconds
|
#define COMBOBOX_ANIMATION_DURATION 200 // In milliseconds
|
||||||
|
|
||||||
|
#define wxMSW_DESKTOP_USERPREFERENCESMASK_COMBOBOXANIM (1<<26)
|
||||||
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// implementation
|
// implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -80,6 +85,7 @@
|
|||||||
BEGIN_EVENT_TABLE(wxComboCtrl, wxComboCtrlBase)
|
BEGIN_EVENT_TABLE(wxComboCtrl, wxComboCtrlBase)
|
||||||
EVT_PAINT(wxComboCtrl::OnPaintEvent)
|
EVT_PAINT(wxComboCtrl::OnPaintEvent)
|
||||||
EVT_MOUSE_EVENTS(wxComboCtrl::OnMouseEvent)
|
EVT_MOUSE_EVENTS(wxComboCtrl::OnMouseEvent)
|
||||||
|
EVT_TIMER(wxID_ANY, wxComboCtrl::OnTimerEvent)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
|
||||||
@@ -530,7 +536,7 @@ void wxComboCtrl::OnMouseEvent( wxMouseEvent& event )
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(__WXWINCE__)
|
#if wxUSE_COMBOCTRL_POPUP_ANIMATION
|
||||||
static wxUint32 GetUserPreferencesMask()
|
static wxUint32 GetUserPreferencesMask()
|
||||||
{
|
{
|
||||||
static wxUint32 userPreferencesMask = 0;
|
static wxUint32 userPreferencesMask = 0;
|
||||||
@@ -559,64 +565,83 @@ static wxUint32 GetUserPreferencesMask()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool wxComboCtrl::AnimateShow( const wxRect& rect, int flags )
|
#if wxUSE_COMBOCTRL_POPUP_ANIMATION
|
||||||
|
void wxComboCtrl::OnTimerEvent( wxTimerEvent& WXUNUSED(event) )
|
||||||
{
|
{
|
||||||
#if !defined(__WXWINCE__)
|
bool stopTimer = false;
|
||||||
if ( GetUserPreferencesMask() & (1<<26) )
|
|
||||||
{
|
|
||||||
wxLongLong tStart = ::wxGetLocalTimeMillis();
|
|
||||||
|
|
||||||
int height = rect.height;
|
|
||||||
|
|
||||||
wxWindow* win = GetPopupWindow();
|
|
||||||
wxWindow* popup = GetPopupControl()->GetControl();
|
wxWindow* popup = GetPopupControl()->GetControl();
|
||||||
|
|
||||||
const int delay = COMBOBOX_ANIMATION_DURATION;
|
// Popup was hidden before it was fully shown?
|
||||||
const int resolution = 10;
|
if ( IsPopupWindowState(Hidden) )
|
||||||
int h0 = popup->GetSize().y;
|
{
|
||||||
|
stopTimer = true;
|
||||||
win->SetSize( rect.x, rect.y, rect.width, 0 );
|
}
|
||||||
win->Show();
|
else
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
{
|
||||||
wxLongLong t = ::wxGetLocalTimeMillis();
|
wxLongLong t = ::wxGetLocalTimeMillis();
|
||||||
int pos = (int) (t-tStart).GetLo();
|
const wxRect& rect = m_animRect;
|
||||||
if ( pos > delay )
|
wxWindow* win = GetPopupWindow();
|
||||||
break;
|
|
||||||
|
|
||||||
int h = (((pos*256)/delay)*height)/256;
|
int pos = (int) (t-m_animStart).GetLo();
|
||||||
int y = (h0 - h);
|
if ( pos < COMBOBOX_ANIMATION_DURATION )
|
||||||
|
{
|
||||||
|
int height = rect.height;
|
||||||
|
//int h0 = rect.height;
|
||||||
|
int h = (((pos*256)/COMBOBOX_ANIMATION_DURATION)*height)/256;
|
||||||
|
int y = (height - h);
|
||||||
if ( y < 0 )
|
if ( y < 0 )
|
||||||
y = 0;
|
y = 0;
|
||||||
|
|
||||||
if ( flags & ShowAbove )
|
if ( m_animFlags & ShowAbove )
|
||||||
{
|
{
|
||||||
win->SetSize( rect.x, rect.y + h0 - h, rect.width, h );
|
win->SetSize( rect.x, rect.y + height - h, rect.width, h );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
popup->Move( 0, -y );
|
popup->Move( 0, -y );
|
||||||
win->SetSize( rect.x, rect.y, rect.width, h );
|
win->SetSize( rect.x, rect.y, rect.width, h );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
wxMilliSleep( resolution );
|
else
|
||||||
wxYield();
|
{
|
||||||
|
stopTimer = true;
|
||||||
// Popup was hidden before it was fully shown?
|
}
|
||||||
if ( IsPopupWindowState(Hidden) )
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( stopTimer )
|
||||||
|
{
|
||||||
popup->Move( 0, 0 );
|
popup->Move( 0, 0 );
|
||||||
|
m_animTimer.Stop();
|
||||||
|
DoShowPopup( m_animRect, m_animFlags );
|
||||||
}
|
}
|
||||||
#else
|
}
|
||||||
wxUnusedVar(rect);
|
|
||||||
wxUnusedVar(flags);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if wxUSE_COMBOCTRL_POPUP_ANIMATION
|
||||||
|
bool wxComboCtrl::AnimateShow( const wxRect& rect, int flags )
|
||||||
|
{
|
||||||
|
if ( GetUserPreferencesMask() & wxMSW_DESKTOP_USERPREFERENCESMASK_COMBOBOXANIM )
|
||||||
|
{
|
||||||
|
m_animStart = ::wxGetLocalTimeMillis();
|
||||||
|
m_animRect = rect;
|
||||||
|
m_animFlags = flags;
|
||||||
|
|
||||||
|
wxWindow* win = GetPopupWindow();
|
||||||
|
win->SetSize( rect.x, rect.y, rect.width, 0 );
|
||||||
|
win->Show();
|
||||||
|
|
||||||
|
m_animTimer.SetOwner( this, wxID_ANY );
|
||||||
|
m_animTimer.Start( COMBOBOX_ANIMATION_RESOLUTION, wxTIMER_CONTINUOUS );
|
||||||
|
|
||||||
|
OnTimerEvent(*((wxTimerEvent*)NULL)); // Event is never used, so we can give NULL
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
wxCoord wxComboCtrl::GetNativeTextIndent() const
|
wxCoord wxComboCtrl::GetNativeTextIndent() const
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user