[ 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:
parent
9985801dda
commit
974a12f86a
@ -213,6 +213,25 @@ appropriately.}
|
||||
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}
|
||||
|
||||
\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.
|
||||
|
||||
|
||||
\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}
|
||||
|
||||
\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.
|
||||
|
||||
|
||||
\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}
|
||||
|
||||
\constfunc{long}{GetLastPosition}{\void}
|
||||
|
@ -152,7 +152,7 @@ public:
|
||||
virtual void OnButtonClick();
|
||||
|
||||
// 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
|
||||
// NULL popup can be used to indicate default in a derived class
|
||||
@ -350,7 +350,7 @@ public:
|
||||
bool ShouldDrawFocus() const
|
||||
{
|
||||
const wxWindow* curFocus = FindFocus();
|
||||
return ( !m_isPopupShown &&
|
||||
return ( !IsPopupShown() &&
|
||||
(curFocus == this || (m_btn && curFocus == m_btn)) &&
|
||||
(m_windowStyle & wxCB_READONLY) );
|
||||
}
|
||||
@ -370,6 +370,19 @@ public:
|
||||
// common code to be called on popup hide/dismiss
|
||||
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:
|
||||
|
||||
//
|
||||
@ -447,6 +460,23 @@ protected:
|
||||
// Dispatches size event and refreshes
|
||||
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
|
||||
virtual void DoSetToolTip( wxToolTip *tip );
|
||||
#endif
|
||||
@ -540,7 +570,7 @@ protected:
|
||||
bool m_blankButtonBg;
|
||||
|
||||
// is the popup window currenty shown?
|
||||
bool m_isPopupShown;
|
||||
wxByte m_popupWinState;
|
||||
|
||||
private:
|
||||
void Init();
|
||||
|
@ -60,6 +60,7 @@ public:
|
||||
virtual ~wxComboCtrl();
|
||||
|
||||
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;
|
||||
|
||||
static int GetFeatures() { return wxComboCtrlFeatures::All; }
|
||||
|
@ -85,6 +85,9 @@ public:
|
||||
|
||||
void OnIdle( wxIdleEvent& event );
|
||||
|
||||
|
||||
wxCheckBox* m_cbUseAnim;
|
||||
|
||||
protected:
|
||||
wxTextCtrl* m_logWin;
|
||||
wxLog* m_logOld;
|
||||
@ -490,6 +493,66 @@ BEGIN_EVENT_TABLE(TreeCtrlComboPopup, wxTreeCtrl)
|
||||
EVT_LEFT_DOWN(TreeCtrlComboPopup::OnMouseClick)
|
||||
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)
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -730,8 +793,8 @@ MyFrame::MyFrame(const wxString& title)
|
||||
colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
|
||||
|
||||
rowSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
cc = new wxComboCtrl(panel,2,wxEmptyString,
|
||||
wxDefaultPosition, wxDefaultSize);
|
||||
cc = new wxComboCtrlWithCustomPopupAnim();
|
||||
cc->Create(panel, wxID_ANY, wxEmptyString);
|
||||
|
||||
// Make sure we use popup that allows focusing the listview.
|
||||
cc->UseAltPopupWindow();
|
||||
@ -879,7 +942,23 @@ MyFrame::MyFrame(const wxString& title)
|
||||
|
||||
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 );
|
||||
|
||||
panel->SetSizer( topSizer );
|
||||
|
@ -44,10 +44,6 @@
|
||||
// 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 BMP_BUTTON_MARGIN 4
|
||||
@ -344,20 +340,50 @@ public:
|
||||
style)
|
||||
#endif
|
||||
{
|
||||
m_inShow = 0;
|
||||
}
|
||||
|
||||
#if USES_WXPOPUPTRANSIENTWINDOW
|
||||
virtual bool Show( bool show );
|
||||
virtual bool ProcessLeftDown(wxMouseEvent& event);
|
||||
virtual void OnDismiss();
|
||||
#endif
|
||||
|
||||
private:
|
||||
wxByte m_inShow;
|
||||
};
|
||||
|
||||
|
||||
#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.
|
||||
@ -387,6 +413,7 @@ public:
|
||||
m_combo = parent;
|
||||
}
|
||||
|
||||
void OnSizeEvent( wxSizeEvent& event );
|
||||
void OnKeyEvent(wxKeyEvent& event);
|
||||
#if USES_WXDIALOG
|
||||
void OnActivate( wxActivateEvent& event );
|
||||
@ -405,9 +432,15 @@ BEGIN_EVENT_TABLE(wxComboPopupWindowEvtHandler, wxEvtHandler)
|
||||
#if USES_WXDIALOG
|
||||
EVT_ACTIVATE(wxComboPopupWindowEvtHandler::OnActivate)
|
||||
#endif
|
||||
EVT_SIZE(wxComboPopupWindowEvtHandler::OnSizeEvent)
|
||||
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 )
|
||||
{
|
||||
// Relay keyboard event to the main child controls
|
||||
@ -621,7 +654,7 @@ void wxComboPopupExtraEventHandler::OnMouseEvent( wxMouseEvent& event )
|
||||
evtType == wxEVT_RIGHT_DOWN )
|
||||
{
|
||||
// Block motion and click events outside the popup
|
||||
if ( !isInside )
|
||||
if ( !isInside || !m_combo->IsPopupShown() )
|
||||
{
|
||||
event.Skip(false);
|
||||
return;
|
||||
@ -629,11 +662,10 @@ void wxComboPopupExtraEventHandler::OnMouseEvent( wxMouseEvent& event )
|
||||
}
|
||||
else if ( evtType == wxEVT_LEFT_UP )
|
||||
{
|
||||
// Don't let left-down events in if outside
|
||||
if ( evtType == wxEVT_LEFT_DOWN )
|
||||
if ( !m_combo->IsPopupShown() )
|
||||
{
|
||||
if ( !isInside )
|
||||
return;
|
||||
event.Skip(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !m_beenInside )
|
||||
@ -688,7 +720,7 @@ void wxComboCtrlBase::Init()
|
||||
{
|
||||
m_winPopup = (wxWindow *)NULL;
|
||||
m_popup = (wxWindow *)NULL;
|
||||
m_isPopupShown = false;
|
||||
m_popupWinState = Hidden;
|
||||
m_btn = (wxWindow*) NULL;
|
||||
m_text = (wxTextCtrl*) NULL;
|
||||
m_popupInterface = (wxComboPopup*) NULL;
|
||||
@ -1212,7 +1244,7 @@ void wxComboCtrlBase::DrawButton( wxDC& dc, const wxRect& rect, bool paintBg )
|
||||
int drawState = m_btnState;
|
||||
|
||||
#ifdef __WXGTK__
|
||||
if ( m_isPopupShown )
|
||||
if ( GetPopupWindowState() >= Animating )
|
||||
drawState |= wxCONTROL_PRESSED;
|
||||
#endif
|
||||
|
||||
@ -1365,7 +1397,7 @@ bool wxComboCtrlBase::HandleButtonMouseEvent( wxMouseEvent& event,
|
||||
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) )
|
||||
{
|
||||
@ -1406,7 +1438,7 @@ bool wxComboCtrlBase::HandleButtonMouseEvent( wxMouseEvent& event,
|
||||
m_btnState &= ~(wxCONTROL_CURRENT);
|
||||
|
||||
// Mouse hover ends
|
||||
if ( !m_isPopupShown )
|
||||
if ( IsPopupWindowState(Hidden) )
|
||||
{
|
||||
m_btnState &= ~(wxCONTROL_PRESSED);
|
||||
Refresh();
|
||||
@ -1429,7 +1461,7 @@ bool wxComboCtrlBase::PreprocessMouseEvent( wxMouseEvent& event,
|
||||
#if USES_WXPOPUPWINDOW || USES_WXDIALOG
|
||||
if ( m_popupWinType != POPUPWIN_WXPOPUPTRANSIENTWINDOW )
|
||||
{
|
||||
if ( m_isPopupShown &&
|
||||
if ( IsPopupWindowState(Visible) &&
|
||||
( evtType == wxEVT_LEFT_DOWN || evtType == wxEVT_RIGHT_DOWN ) )
|
||||
{
|
||||
HidePopup();
|
||||
@ -1455,7 +1487,7 @@ void wxComboCtrlBase::HandleNormalMouseEvent( wxMouseEvent& event )
|
||||
if ( (evtType == wxEVT_LEFT_DOWN || evtType == wxEVT_LEFT_DCLICK) &&
|
||||
(m_windowStyle & wxCB_READONLY) )
|
||||
{
|
||||
if ( m_isPopupShown )
|
||||
if ( GetPopupWindowState() >= Animating )
|
||||
{
|
||||
#if USES_WXPOPUPWINDOW
|
||||
// Click here always hides the popup.
|
||||
@ -1481,7 +1513,7 @@ void wxComboCtrlBase::HandleNormalMouseEvent( wxMouseEvent& event )
|
||||
}
|
||||
}
|
||||
else
|
||||
if ( m_isPopupShown )
|
||||
if ( IsPopupShown() )
|
||||
{
|
||||
// relay (some) mouse events to the popup
|
||||
if ( evtType == wxEVT_MOUSEWHEEL )
|
||||
@ -1677,7 +1709,10 @@ void wxComboCtrlBase::OnButtonClick()
|
||||
void wxComboCtrlBase::ShowPopup()
|
||||
{
|
||||
EnsurePopupControl();
|
||||
wxCHECK_RET( !IsPopupShown(), wxT("popup window already shown") );
|
||||
wxCHECK_RET( !IsPopupWindowState(Visible), wxT("popup window already shown") );
|
||||
|
||||
if ( IsPopupWindowState(Animating) )
|
||||
return;
|
||||
|
||||
SetFocus();
|
||||
|
||||
@ -1793,22 +1828,27 @@ void wxComboCtrlBase::ShowPopup()
|
||||
else
|
||||
popupX = 0;
|
||||
|
||||
int showFlags = CanDeferShow;
|
||||
|
||||
if ( spaceBelow < szp.y )
|
||||
{
|
||||
popupY = scrPos.y - szp.y;
|
||||
showFlags |= ShowAbove;
|
||||
}
|
||||
|
||||
// Move to position
|
||||
//wxLogDebug(wxT("popup scheduled position1: %i,%i"),ptp.x,ptp.y);
|
||||
//wxLogDebug(wxT("popup position1: %i,%i"),winPopup->GetPosition().x,winPopup->GetPosition().y);
|
||||
#if INSTALL_TOPLEV_HANDLER
|
||||
// Put top level window event handler into place
|
||||
if ( m_popupWinType == POPUPWIN_WXPOPUPWINDOW )
|
||||
{
|
||||
if ( !m_toplevEvtHandler )
|
||||
m_toplevEvtHandler = new wxComboFrameEventHandler(this);
|
||||
|
||||
// Some platforms (GTK) may need these two to be separate
|
||||
winPopup->SetSize( szp.x, szp.y );
|
||||
winPopup->Move( popupX, popupY );
|
||||
|
||||
//wxLogDebug(wxT("popup position2: %i,%i"),winPopup->GetPosition().x,winPopup->GetPosition().y);
|
||||
|
||||
m_popup = popup;
|
||||
wxWindow* toplev = ::wxGetTopLevelParent( this );
|
||||
wxASSERT( toplev );
|
||||
((wxComboFrameEventHandler*)m_toplevEvtHandler)->OnPopup();
|
||||
toplev->PushEventHandler( m_toplevEvtHandler );
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set string selection (must be this way instead of SetStringSelection)
|
||||
if ( m_text )
|
||||
@ -1825,51 +1865,68 @@ void wxComboCtrlBase::ShowPopup()
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
||||
#if INSTALL_TOPLEV_HANDLER
|
||||
// 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 );
|
||||
m_popupWinState = Visible;
|
||||
}
|
||||
#endif
|
||||
else if ( IsPopupWindowState(Hidden) )
|
||||
{
|
||||
// Animation was aborted
|
||||
|
||||
wxASSERT( !winPopup->IsShown() );
|
||||
|
||||
m_popupWinState = Hidden;
|
||||
}
|
||||
}
|
||||
|
||||
void wxComboCtrlBase::OnPopupDismiss()
|
||||
{
|
||||
{
|
||||
// Just in case, avoid double dismiss
|
||||
if ( !m_isPopupShown )
|
||||
if ( IsPopupWindowState(Hidden) )
|
||||
return;
|
||||
|
||||
// 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
|
||||
// SetFocus is called also here, exactly before m_popupWinState
|
||||
// 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).
|
||||
// that (ie. does not care about m_popupWinState).
|
||||
|
||||
SetFocus();
|
||||
|
||||
// This should preferably be set before focus.
|
||||
m_isPopupShown = false;
|
||||
m_popupWinState = Hidden;
|
||||
|
||||
// Inform popup control itself
|
||||
m_popupInterface->OnDismiss();
|
||||
@ -1887,7 +1944,10 @@ void wxComboCtrlBase::OnPopupDismiss()
|
||||
}
|
||||
#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
|
||||
// (technically not required by all ports, but do it for all just in case)
|
||||
@ -1912,19 +1972,14 @@ void wxComboCtrlBase::OnPopupDismiss()
|
||||
void wxComboCtrlBase::HidePopup()
|
||||
{
|
||||
// Should be able to call this without popup interface
|
||||
//wxCHECK_RET( m_popupInterface, _T("no popup interface") );
|
||||
if ( !m_isPopupShown )
|
||||
if ( IsPopupWindowState(Hidden) )
|
||||
return;
|
||||
|
||||
// transfer value and show it in textctrl, if any
|
||||
SetValue( m_popupInterface->GetStringValue() );
|
||||
if ( !IsPopupWindowState(Animating) )
|
||||
SetValue( m_popupInterface->GetStringValue() );
|
||||
|
||||
#if USES_WXPOPUPTRANSIENTWINDOW
|
||||
if ( m_popupWinType == POPUPWIN_WXPOPUPTRANSIENTWINDOW )
|
||||
((wxPopupTransientWindow*)m_winPopup)->Dismiss();
|
||||
else
|
||||
#endif
|
||||
m_winPopup->Hide();
|
||||
m_winPopup->Hide();
|
||||
|
||||
OnPopupDismiss();
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
||||
|
||||
#include "wx/combo.h"
|
||||
|
||||
|
||||
#include "wx/msw/registry.h"
|
||||
#include "wx/msw/uxtheme.h"
|
||||
|
||||
// Change to #if 1 to include tmschema.h for easier testing of theme
|
||||
@ -70,6 +70,7 @@
|
||||
#define TEXTCTRLXADJUST_CLASSIC 1
|
||||
#define TEXTCTRLYADJUST_CLASSIC 2
|
||||
|
||||
#define COMBOBOX_ANIMATION_DURATION 200 // In milliseconds
|
||||
|
||||
// ============================================================================
|
||||
// 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
|
||||
{
|
||||
if ( wxUxThemeEngine::GetIfActive() )
|
||||
|
Loading…
Reference in New Issue
Block a user