]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/combocmn.cpp
wxMessageBox off the main thread lost result code.
[wxWidgets.git] / src / common / combocmn.cpp
index 438a3e27908f7731749cf243e8bea4669f7e8dd1..82d16579609d4571ecf5fdb19d9b0b3fe4bc02ff 100644 (file)
@@ -4,7 +4,6 @@
 // Author:      Jaakko Salli
 // Modified by:
 // Created:     Apr-30-2006
-// RCS-ID:      $Id$
 // Copyright:   (c) 2005 Jaakko Salli
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
     #pragma hdrstop
 #endif
 
-#if wxUSE_COMBOBOX
-#include "wx/combobox.h"
-extern WXDLLEXPORT_DATA(const char) wxComboBoxNameStr[] = "comboBox";
-#endif
-
-#if wxUSE_COMBOCTRL
+#include "wx/combo.h"
 
-#ifndef WX_PRECOMP
-    #include "wx/app.h"
-    #include "wx/log.h"
-    #include "wx/dcclient.h"
-    #include "wx/settings.h"
-    #include "wx/timer.h"
-    #include "wx/textctrl.h"
+#ifdef __WXMSW__
+#include "wx/msw/private.h"
 #endif
 
-#include "wx/tooltip.h"
-
-#include "wx/combo.h"
-
+#if wxUSE_COMBOBOX
+#include "wx/combobox.h"
+extern WXDLLEXPORT_DATA(const char) wxComboBoxNameStr[] = "comboBox";
 
 // ----------------------------------------------------------------------------
 // XTI
@@ -87,8 +75,8 @@ wxEND_FLAGS( wxComboBoxStyle )
 wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxComboBox, wxControl, "wx/combobox.h")
 
 wxBEGIN_PROPERTIES_TABLE(wxComboBox)
-wxEVENT_PROPERTY( Select, wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEvent )
-wxEVENT_PROPERTY( TextEnter, wxEVT_COMMAND_TEXT_ENTER, wxCommandEvent )
+wxEVENT_PROPERTY( Select, wxEVT_COMBOBOX, wxCommandEvent )
+wxEVENT_PROPERTY( TextEnter, wxEVT_TEXT_ENTER, wxCommandEvent )
 
 // TODO DELEGATES
 wxPROPERTY( Font, wxFont, SetFont, GetFont, wxEMPTY_PARAMETER_VALUE, \
@@ -110,6 +98,21 @@ wxEMPTY_HANDLERS_TABLE(wxComboBox)
 wxCONSTRUCTOR_5( wxComboBox, wxWindow*, Parent, wxWindowID, Id, \
                 wxString, Value, wxPoint, Position, wxSize, Size )
 
+#endif // wxUSE_COMBOBOX
+
+#if wxUSE_COMBOCTRL
+
+#ifndef WX_PRECOMP
+    #include "wx/app.h"
+    #include "wx/log.h"
+    #include "wx/dcclient.h"
+    #include "wx/settings.h"
+    #include "wx/timer.h"
+    #include "wx/textctrl.h"
+#endif
+
+#include "wx/tooltip.h"
+
 // constants
 // ----------------------------------------------------------------------------
 
@@ -389,7 +392,7 @@ void wxComboFrameEventHandler::OnIdle( wxIdleEvent& event )
     wxWindow* popup = m_combo->GetPopupControl()->GetControl();
     wxWindow* winpopup = m_combo->GetPopupWindow();
 
-    if (
+    if ( !winFocused || (
          winFocused != m_focusStart &&
          winFocused != popup &&
          winFocused->GetParent() != popup &&
@@ -398,6 +401,7 @@ void wxComboFrameEventHandler::OnIdle( wxIdleEvent& event )
          winFocused != m_combo &&
          winFocused != m_combo->GetButton() // GTK (atleast) requires this
         )
+       )
     {
         m_combo->HidePopup(true);
     }
@@ -1095,10 +1099,10 @@ wxComboCtrlBase::CreateTextCtrl(int style)
 
         // Connecting the events is currently the most reliable way
         wxWindowID id = m_text->GetId();
-        m_text->Connect(id, wxEVT_COMMAND_TEXT_UPDATED,
+        m_text->Connect(id, wxEVT_TEXT,
                         wxCommandEventHandler(wxComboCtrlBase::OnTextCtrlEvent),
                         NULL, this);
-        m_text->Connect(id, wxEVT_COMMAND_TEXT_ENTER,
+        m_text->Connect(id, wxEVT_TEXT_ENTER,
                         wxCommandEventHandler(wxComboCtrlBase::OnTextCtrlEvent),
                         NULL, this);
 
@@ -1359,20 +1363,50 @@ void wxComboCtrlBase::PositionTextCtrl( int textCtrlXAdjust, int textCtrlYAdjust
 
 wxSize wxComboCtrlBase::DoGetBestSize() const
 {
-    wxSize sizeText(150,0);
+    int width = m_text ? m_text->GetBestSize().x : 80;
 
-    if ( m_text )
-        sizeText = m_text->GetBestSize();
+    return GetSizeFromTextSize(width);
+}
 
-    // TODO: Better method to calculate close-to-native control height.
+wxSize wxComboCtrlBase::DoGetSizeFromTextSize(int xlen, int ylen) const
+{
+    // Calculate close-to-native control height
 
     int fhei;
+
+#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
+    fhei = EDIT_HEIGHT_FROM_CHAR_HEIGHT(GetCharHeight());
+#elif defined(__WXGTK__) && !defined(__WXUNIVERSAL__)
+    // Control creation is not entirely cheap, so cache the heights to
+    // avoid repeatedly creating dummy controls:
+    static wxString s_last_font;
+    static int s_last_fhei = -1;
+    wxString fontdesc;
+    if ( m_font.IsOk() )
+        fontdesc = m_font.GetNativeFontInfoDesc();
+    if ( s_last_fhei != -1 && fontdesc == s_last_font )
+    {
+        fhei = s_last_fhei;
+    }
+    else
+    {
+        wxComboBox* cb = new wxComboBox;
+        cb->Hide();
+        cb->Create(const_cast<wxComboCtrlBase*>(this), wxID_ANY);
+        if ( m_font.IsOk() )
+            cb->SetFont(m_font);
+        s_last_font = fontdesc;
+        s_last_fhei = fhei = cb->GetBestSize().y;
+        cb->Destroy();
+    }
+#else
     if ( m_font.IsOk() )
         fhei = (m_font.GetPointSize()*2) + 5;
     else if ( wxNORMAL_FONT->IsOk() )
         fhei = (wxNORMAL_FONT->GetPointSize()*2) + 5;
     else
-        fhei = sizeText.y + 4;
+        fhei = 22;
+#endif // only for wxComboBox on MSW or GTK
 
     // Need to force height to accommodate bitmap?
     int btnSizeY = m_btnSize.y;
@@ -1392,11 +1426,6 @@ wxSize wxComboCtrlBase::DoGetBestSize() const
         fhei += 4;
 */
 
-    // Final adjustments
-#ifdef __WXGTK__
-    fhei += 1;
-#endif
-
 #ifdef __WXMAC__
     // these are the numbers from the HIG:
     switch ( m_windowVariant )
@@ -1415,11 +1444,19 @@ wxSize wxComboCtrlBase::DoGetBestSize() const
 #endif
 
     fhei += 2 * FOCUS_RING;
-    int width = sizeText.x + FOCUS_RING + COMBO_MARGIN + DEFAULT_DROPBUTTON_WIDTH;
 
-    wxSize ret(width, fhei);
-    CacheBestSize(ret);
-    return ret;
+    // Calculate width
+    int fwid = xlen + FOCUS_RING + COMBO_MARGIN + DEFAULT_DROPBUTTON_WIDTH;
+
+    // Add the margins we have previously set
+    wxPoint marg( GetMargins() );
+    fwid += wxMax(0, marg.x);
+    fhei += wxMax(0, marg.y);
+
+    if ( ylen > 0 )
+        fhei += ylen - GetCharHeight();
+
+    return wxSize(fwid, fhei);
 }
 
 void wxComboCtrlBase::OnSizeEvent( wxSizeEvent& event )
@@ -1770,7 +1807,7 @@ void wxComboCtrlBase::OnTextCtrlEvent(wxCommandEvent& event)
         return;
     }
 
-    if ( event.GetEventType() == wxEVT_COMMAND_TEXT_UPDATED )
+    if ( event.GetEventType() == wxEVT_TEXT )
     {
         if ( m_ignoreEvtText > 0 )
         {
@@ -2033,19 +2070,23 @@ void wxComboCtrlBase::OnCharEvent(wxKeyEvent& event)
 
 void wxComboCtrlBase::OnFocusEvent( wxFocusEvent& event )
 {
-// On Mac, this leads to infinite recursion and eventually a crash 
-#ifndef __WXMAC__
+    // On Mac, setting focus here leads to infinite recursion and eventually
+    // a crash due to the SetFocus call producing another event.
+    // Handle Mac in OnIdleEvent using m_resetFocus.
+    
     if ( event.GetEventType() == wxEVT_SET_FOCUS )
     {
-        wxWindow* tc = GetTextCtrl();
-        if ( tc && tc != DoFindFocus() )
+        if ( GetTextCtrl() && !GetTextCtrl()->HasFocus() )
         {
-            tc->SetFocus();
+#ifdef __WXMAC__
+            m_resetFocus = true;
+#else
+            GetTextCtrl()->SetFocus();
+#endif
         }
     }
-
+    
     Refresh();
-#endif
 }
 
 void wxComboCtrlBase::OnIdleEvent( wxIdleEvent& WXUNUSED(event) )
@@ -2053,9 +2094,8 @@ void wxComboCtrlBase::OnIdleEvent( wxIdleEvent& WXUNUSED(event) )
     if ( m_resetFocus )
     {
         m_resetFocus = false;
-        wxWindow* tc = GetTextCtrl();
-        if ( tc )
-            tc->SetFocus();
+        if ( GetTextCtrl() )
+            GetTextCtrl()->SetFocus();
     }
 }
 
@@ -2213,7 +2253,7 @@ void wxComboCtrlBase::OnButtonClick()
 
 void wxComboCtrlBase::Popup()
 {
-    wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_DROPDOWN, GetId());
+    wxCommandEvent event(wxEVT_COMBOBOX_DROPDOWN, GetId());
     event.SetEventObject(this);
     HandleWindowEvent(event);
 
@@ -2499,7 +2539,7 @@ void wxComboCtrlBase::OnPopupDismiss(bool generateEvent)
 
     if ( generateEvent )
     {
-        wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_CLOSEUP, GetId());
+        wxCommandEvent event(wxEVT_COMBOBOX_CLOSEUP, GetId());
         event.SetEventObject(this);
         HandleWindowEvent(event);
     }