X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e83844692e1e83324e9eaa5e9009d55df6df83b7..e4de825ee6f3f991e2aa86159d6e3457afb6a8e0:/samples/combo/combo.cpp?ds=sidebyside diff --git a/samples/combo/combo.cpp b/samples/combo/combo.cpp index 5f8e7fea59..8123b5a7be 100644 --- a/samples/combo/combo.cpp +++ b/samples/combo/combo.cpp @@ -83,6 +83,11 @@ public: // log wxComboCtrl events void OnComboBoxUpdate( wxCommandEvent& event ); + void OnIdle( wxIdleEvent& event ); + + + wxCheckBox* m_cbUseAnim; + protected: wxTextCtrl* m_logWin; wxLog* m_logOld; @@ -127,6 +132,8 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(ComboControl_Compare, MyFrame::OnShowComparison) EVT_MENU(ComboControl_Quit, MyFrame::OnQuit) EVT_MENU(ComboControl_About, MyFrame::OnAbout) + + EVT_IDLE(MyFrame::OnIdle) END_EVENT_TABLE() // Create a new application object: this macro will allow wxWidgets to create @@ -147,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")); @@ -230,8 +240,7 @@ public: // If item is selected or even, or we are painting the // combo control itself, use the default rendering. - if ( GetVListBoxComboPopup()->IsCurrent((size_t)item) || - (flags & wxODCB_PAINTING_CONTROL) || + if ( (flags & (wxODCB_PAINTING_CONTROL|wxODCB_PAINTING_SELECTED)) || (item & 1) == 0 ) { wxOwnerDrawnComboBox::OnDrawBackground(dc,rect,item,flags); @@ -374,9 +383,7 @@ public: { return wxTreeCtrl::Create(parent,1, wxPoint(0,0),wxDefaultSize, - wxTR_HIDE_ROOT|wxTR_HAS_BUTTONS| - wxTR_SINGLE|wxTR_LINES_AT_ROOT| - wxSIMPLE_BORDER); + wxTR_DEFAULT_STYLE | wxTR_HIDE_ROOT | wxSIMPLE_BORDER ); } virtual void OnShow() @@ -487,6 +494,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) // ---------------------------------------------------------------------------- @@ -617,7 +745,7 @@ MyFrame::MyFrame(const wxString& title) m_logWin->SetEditable(false); wxLogTextCtrl* logger = new wxLogTextCtrl( m_logWin ); m_logOld = logger->SetActiveTarget( logger ); - logger->SetTimestamp( NULL ); + logger->DisableTimestamp(); topSizer = new wxBoxSizer( wxVERTICAL ); @@ -628,7 +756,7 @@ MyFrame::MyFrame(const wxString& title) wxComboCtrl* cc; - wxGenericComboControl* gcc; + wxGenericComboCtrl* gcc; wxOwnerDrawnComboBox* odc; // Create common strings array @@ -727,8 +855,11 @@ 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(); cc->SetPopupMinWidth(300); @@ -746,9 +877,12 @@ MyFrame::MyFrame(const wxString& title) // Tree Ctrl wxComboCtrl // - // Note that we test that wxGenericComboControl works - gcc = new wxGenericComboControl(panel,wxID_ANY,wxEmptyString, - wxDefaultPosition, wxDefaultSize); + // Note that we test that wxGenericComboCtrl works + gcc = new wxGenericComboCtrl(panel,wxID_ANY,wxEmptyString, + wxDefaultPosition, wxDefaultSize); + + // Make sure we use popup that allows focusing the treectrl. + gcc->UseAltPopupWindow(); // Set popup interface right away, otherwise some of the calls // below may fail @@ -818,7 +952,7 @@ MyFrame::MyFrame(const wxString& title) wxImage imgPressed(wxT("dropbutp.png")); wxImage imgHover(wxT("dropbuth.png")); - if ( imgNormal.Ok() && imgPressed.Ok() && imgHover.Ok() ) + if ( imgNormal.IsOk() && imgPressed.IsOk() && imgHover.IsOk() ) { wxBitmap bmpNormal(imgNormal); wxBitmap bmpPressed(imgPressed); @@ -870,7 +1004,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 ); @@ -1060,3 +1210,27 @@ void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) wxOK | wxICON_INFORMATION, 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(""); + if ( curFocus ) + className = curFocus->GetClassInfo()->GetClassName(); + lastFocus = curFocus; + wxLogDebug( wxT("FOCUSED: %s %X"), + className, + (unsigned int)curFocus); + } +#endif + + event.Skip(); +}