// 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
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, \
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
// ----------------------------------------------------------------------------
wxWindow* popup = m_combo->GetPopupControl()->GetControl();
wxWindow* winpopup = m_combo->GetPopupWindow();
- if (
+ if ( !winFocused || (
winFocused != m_focusStart &&
winFocused != popup &&
winFocused->GetParent() != popup &&
winFocused != m_combo &&
winFocused != m_combo->GetButton() // GTK (atleast) requires this
)
+ )
{
m_combo->HidePopup(true);
}
// 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);
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;
fhei += 4;
*/
- // Final adjustments
-#ifdef __WXGTK__
- fhei += 1;
-#endif
-
#ifdef __WXMAC__
// these are the numbers from the HIG:
switch ( m_windowVariant )
#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 )
return;
}
- if ( event.GetEventType() == wxEVT_COMMAND_TEXT_UPDATED )
+ if ( event.GetEventType() == wxEVT_TEXT )
{
if ( m_ignoreEvtText > 0 )
{
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) )
if ( m_resetFocus )
{
m_resetFocus = false;
- wxWindow* tc = GetTextCtrl();
- if ( tc )
- tc->SetFocus();
+ if ( GetTextCtrl() )
+ GetTextCtrl()->SetFocus();
}
}
void wxComboCtrlBase::Popup()
{
- wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_DROPDOWN, GetId());
+ wxCommandEvent event(wxEVT_COMBOBOX_DROPDOWN, GetId());
event.SetEventObject(this);
HandleWindowEvent(event);
if ( generateEvent )
{
- wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_CLOSEUP, GetId());
+ wxCommandEvent event(wxEVT_COMBOBOX_CLOSEUP, GetId());
event.SetEventObject(this);
HandleWindowEvent(event);
}