X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/06077aaf2c11135bb9ca18ef33181ab18ac7480e..bb650010c8200174ce824aaadac44e8e5ead194d:/samples/combo/combo.cpp diff --git a/samples/combo/combo.cpp b/samples/combo/combo.cpp index 4deda51fec..2d705f1523 100644 --- a/samples/combo/combo.cpp +++ b/samples/combo/combo.cpp @@ -85,6 +85,9 @@ public: void OnIdle( wxIdleEvent& event ); + + wxCheckBox* m_cbUseAnim; + protected: wxTextCtrl* m_logWin; wxLog* m_logOld; @@ -151,6 +154,9 @@ IMPLEMENT_APP(MyApp) // 'Main program' equivalent: the program execution "starts" here bool MyApp::OnInit() { + if ( !wxApp::OnInit() ) + return false; + // create the main application window MyFrame *frame = new MyFrame(_T("wxComboCtrl and wxOwnerDrawnComboBox Sample")); @@ -490,6 +496,127 @@ BEGIN_EVENT_TABLE(TreeCtrlComboPopup, wxTreeCtrl) EVT_LEFT_DOWN(TreeCtrlComboPopup::OnMouseClick) END_EVENT_TABLE() +// ---------------------------------------------------------------------------- +// 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 +{ +public: + + virtual bool AnimateShow( const wxRect& rect, int flags ) + { + MyFrame* myFrame = (MyFrame*) ::wxGetTopLevelParent(this); + + if ( !myFrame->m_cbUseAnim->GetValue() ) + 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 height = rect.height; + + 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 ); + + int w = (((pos*256)/CUSTOM_COMBOBOX_ANIMATION_DURATION)*width)/256; + + double ratio = ((double)w / (double)width); + 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 ); + } + else + { + stopTimer = true; + } + } + + if ( stopTimer ) + { + dc.DrawBitmap( m_animBackBitmap, rect.x, rect.y ); + popup->Move( 0, 0 ); + m_animTimer.Stop(); + DoShowPopup( m_animRect, m_animFlags ); + } + } + +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) // ---------------------------------------------------------------------------- @@ -730,8 +857,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 +1006,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 );