X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ce22ac4592fccaedd8324e7a8f08b510748827e4..d8eff331e23435d9d8d6483a40f6fd9997a13f87:/samples/combo/combo.cpp?ds=sidebyside diff --git a/samples/combo/combo.cpp b/samples/combo/combo.cpp index 5977bc9661..288fbc27e7 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,8 +154,11 @@ 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")); + MyFrame *frame = new MyFrame(wxT("wxComboCtrl and wxOwnerDrawnComboBox Sample")); // and show it (the frames, unlike simple controls, are not shown when // created initially) @@ -373,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() @@ -486,6 +494,130 @@ 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 ); + + DoOnTimer(); + return false; + } + +private: + void OnTimerEvent( wxTimerEvent& WXUNUSED(event) ) + { + DoOnTimer(); + } + + void DoOnTimer() + { + 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 ); + } + } + + // Popup animation related + wxLongLong m_animStart; + wxTimer m_animTimer; + wxRect m_animRect; + wxBitmap m_animBackBitmap; + int m_animFlags; + + 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) // ---------------------------------------------------------------------------- @@ -592,17 +724,17 @@ MyFrame::MyFrame(const wxString& title) // the "About" item should be in the help menu wxMenu *helpMenu = new wxMenu; - helpMenu->Append(ComboControl_About, _T("&About...\tF1"), _T("Show about dialog")); + helpMenu->Append(ComboControl_About, wxT("&About...\tF1"), wxT("Show about dialog")); - fileMenu->Append(ComboControl_Compare, _T("&Compare against wxComboBox..."), - _T("Show some wxOwnerDrawnComboBoxes side-by-side with native wxComboBoxes.")); + fileMenu->Append(ComboControl_Compare, wxT("&Compare against wxComboBox..."), + wxT("Show some wxOwnerDrawnComboBoxes side-by-side with native wxComboBoxes.")); fileMenu->AppendSeparator(); - fileMenu->Append(ComboControl_Quit, _T("E&xit\tAlt-X"), _T("Quit this program")); + fileMenu->Append(ComboControl_Quit, wxT("E&xit\tAlt-X"), wxT("Quit this program")); // now append the freshly created menu to the menu bar... wxMenuBar *menuBar = new wxMenuBar(); - menuBar->Append(fileMenu, _T("&File")); - menuBar->Append(helpMenu, _T("&Help")); + menuBar->Append(fileMenu, wxT("&File")); + menuBar->Append(helpMenu, wxT("&Help")); // ... and attach this menu bar to the frame SetMenuBar(menuBar); @@ -611,12 +743,13 @@ MyFrame::MyFrame(const wxString& title) wxPanel* panel = new wxPanel(this); // Prepare log window right away since it shows EVT_TEXTs - m_logWin = new wxTextCtrl( panel, 105, wxEmptyString, wxDefaultPosition, - wxSize(-1,125), wxTE_MULTILINE|wxFULL_REPAINT_ON_RESIZE ); - m_logWin->SetEditable(false); - wxLogTextCtrl* logger = new wxLogTextCtrl( m_logWin ); - m_logOld = logger->SetActiveTarget( logger ); - logger->SetTimestamp( NULL ); + m_logWin = new wxTextCtrl(panel, 105, wxEmptyString, + wxDefaultPosition, + wxSize(-1, 125), + wxTE_MULTILINE); + wxLogTextCtrl* logger = new wxLogTextCtrl(m_logWin); + m_logOld = logger->SetActiveTarget(logger); + logger->DisableTimestamp(); topSizer = new wxBoxSizer( wxVERTICAL ); @@ -627,7 +760,7 @@ MyFrame::MyFrame(const wxString& title) wxComboCtrl* cc; - wxGenericComboControl* gcc; + wxGenericComboCtrl* gcc; wxOwnerDrawnComboBox* odc; // Create common strings array @@ -726,8 +859,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); @@ -745,9 +881,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 @@ -817,7 +956,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); @@ -869,7 +1008,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 ); @@ -888,9 +1043,13 @@ void MyFrame::OnComboBoxUpdate( wxCommandEvent& event ) return; if ( event.GetEventType() == wxEVT_COMMAND_COMBOBOX_SELECTED ) + { wxLogDebug(wxT("EVT_COMBOBOX(id=%i,selection=%i)"),event.GetId(),event.GetSelection()); + } else if ( event.GetEventType() == wxEVT_COMMAND_TEXT_UPDATED ) + { wxLogDebug(wxT("EVT_TEXT(id=%i,string=\"%s\")"),event.GetId(),event.GetString().c_str()); + } } void MyFrame::OnShowComparison( wxCommandEvent& WXUNUSED(event) ) @@ -1048,14 +1207,38 @@ void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) { wxMessageBox(wxString::Format( - _T("Welcome to %s!\n") - _T("\n") - _T("This is the wxWidgets wxComboCtrl and wxOwnerDrawnComboBox sample\n") - _T("running under %s."), + wxT("Welcome to %s!\n") + wxT("\n") + wxT("This is the wxWidgets wxComboCtrl and wxOwnerDrawnComboBox sample\n") + wxT("running under %s."), wxVERSION_STRING, wxGetOsDescription().c_str() ), - _T("About wxComboCtrl sample"), + wxT("About wxComboCtrl sample"), 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(); +}