/////////////////////////////////////////////////////////////////////////////
-// Name: odcombo.cpp
+// Name: src/generic/odcombo.cpp
// Purpose: wxOwnerDrawnComboBox, wxVListBoxComboPopup
// Author: Jaakko Salli
// Modified by:
#pragma hdrstop
#endif
-#if wxUSE_OWNERDRAWNCOMBOBOX
+#if wxUSE_ODCOMBOBOX
+
+#include "wx/odcombo.h"
#ifndef WX_PRECOMP
#include "wx/log.h"
#endif
#include "wx/combo.h"
-#include "wx/odcombo.h"
-
// ============================================================================
// implementation
END_EVENT_TABLE()
-wxVListBoxComboPopup::wxVListBoxComboPopup(wxComboControlBase* combo)
- : wxVListBox(),
- wxComboPopup(combo)
+void wxVListBoxComboPopup::Init()
{
m_widestWidth = 0;
m_avgCharWidth = 0;
wxBORDER_SIMPLE | wxLB_INT_HEIGHT | wxWANTS_CHARS) )
return false;
- wxASSERT( GetParent()->GetParent() );
- SetFont( GetParent()->GetParent()->GetFont() );
+ m_useFont = m_combo->GetFont();
wxVListBox::SetItemCount(m_strings.GetCount());
m_combo->DrawFocusBackground(dc,rect,0);
if ( m_value >= 0 )
{
- if ( m_combo->OnDrawListItem(dc,rect,m_value,wxCC_PAINTING_CONTROL) )
- return;
+ OnDrawItem(dc,rect,m_value,wxCP_PAINTING_CONTROL);
+ return;
}
}
void wxVListBoxComboPopup::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const
{
- dc.SetFont( m_font );
-
- bool isHilited = GetSelection() == (int) n;
+ // TODO: Maybe this code could be moved to wxVListBox::OnPaint?
+ dc.SetFont(m_useFont);
// Set correct text colour for selected items
- // (must always set the correct colour - atleast GTK may have lost it
- // in between calls).
- if ( isHilited )
+ if ( wxVListBox::GetSelection() == (int) n )
dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT) );
else
dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT) );
- if ( !m_combo->OnDrawListItem(dc,rect,(int)n,0) )
- dc.DrawText( GetString(n), rect.x + 2, rect.y );
+ OnDrawItem(dc,rect,(int)n,0);
}
-wxCoord wxVListBoxComboPopup::OnMeasureItem(size_t n) const
+wxCoord wxVListBoxComboPopup::OnMeasureItem(size_t WXUNUSED(n)) const
{
- int itemHeight = m_combo->OnMeasureListItem(n);
- if ( itemHeight < 0 )
- itemHeight = m_itemHeight;
+ return m_itemHeight;
+}
- return itemHeight;
+wxCoord wxVListBoxComboPopup::OnMeasureItemWidth(size_t WXUNUSED(n)) const
+{
+ //return OnMeasureListItemWidth(n);
+ return -1;
}
void wxVListBoxComboPopup::OnDrawBackground(wxDC& dc, const wxRect& rect, size_t n) const
//else: do nothing for the normal items
}
-void wxVListBoxComboPopup::SendComboBoxEvent()
+// This is called from wxVListBoxComboPopup::OnDrawItem, with text colour and font prepared
+void wxVListBoxComboPopup::OnDrawItem( wxDC& dc, const wxRect& rect, int item, int flags ) const
+{
+ if ( flags & wxCP_PAINTING_CONTROL )
+ {
+ dc.DrawText( m_combo->GetValue(),
+ rect.x + m_combo->GetTextIndent(),
+ (rect.height-dc.GetCharHeight())/2 + rect.y );
+ }
+ else
+ {
+ dc.DrawText( GetString(item), rect.x + 2, rect.y );
+ }
+}
+
+void wxVListBoxComboPopup::DismissWithEvent()
+{
+ int selection = wxVListBox::GetSelection();
+
+ Dismiss();
+
+ wxString valStr;
+ if ( selection != wxNOT_FOUND )
+ valStr = m_strings[selection];
+ else
+ valStr = wxEmptyString;
+
+ m_value = selection;
+
+ if ( valStr != m_combo->GetValue() )
+ m_combo->SetValue(valStr);
+
+ SendComboBoxEvent(selection);
+}
+
+void wxVListBoxComboPopup::SendComboBoxEvent( int selection )
{
wxCommandEvent evt(wxEVT_COMMAND_COMBOBOX_SELECTED,m_combo->GetId());
- int selection = m_value;
evt.SetEventObject(m_combo);
+
evt.SetInt(selection);
// Set client data, if any
{
value-=10;
}
- /*
- else if ( keycode == WXK_END )
- {
- value = itemCount-1;
- }
- else if ( keycode == WXK_HOME )
- {
- value = 0;
- }
- */
else
return false;
m_value = value;
- wxString valStr;
if ( value >= 0 )
m_combo->SetValue(m_strings[value]);
- SendComboBoxEvent();
+ SendComboBoxEvent(m_value);
return true;
}
void wxVListBoxComboPopup::OnLeftClick(wxMouseEvent& WXUNUSED(event))
{
- m_value = wxVListBox::GetSelection();
- Dismiss();
- SendComboBoxEvent();
+ DismissWithEvent();
}
void wxVListBoxComboPopup::OnKey(wxKeyEvent& event)
// Select item if ENTER is pressed
if ( event.GetKeyCode() == WXK_RETURN || event.GetKeyCode() == WXK_NUMPAD_ENTER )
{
- m_value = wxVListBox::GetSelection();
- Dismiss();
- SendComboBoxEvent();
+ DismissWithEvent();
}
// Hide popup if ESC is pressed
else if ( event.GetKeyCode() == WXK_ESCAPE )
void wxVListBoxComboPopup::CheckWidth( int pos )
{
- wxCoord x = m_combo->OnMeasureListItemWidth(pos);
+ wxCoord x = OnMeasureItemWidth(pos);
if ( x < 0 )
{
- if ( !m_font.Ok() )
- m_font = m_combo->GetFont();
+ if ( !m_useFont.Ok() )
+ m_useFont = m_combo->GetFont();
wxCoord y;
- m_combo->GetTextExtent(m_strings[pos], &x, &y, 0, 0, &m_font);
+ m_combo->GetTextExtent(m_strings[pos], &x, &y, 0, 0, &m_useFont);
x += 4;
}
wxString strValue;
if ( !(m_combo->GetWindowStyle() & wxCB_READONLY) &&
m_combo->GetValue() == item )
+ {
m_value = pos;
+ }
m_strings.Insert(item,pos);
ClearClientDatas();
+ m_value = wxNOT_FOUND;
+
if ( IsCreated() )
wxVListBox::SetItemCount(0);
}
void wxVListBoxComboPopup::SetSelection( int item )
{
- // This seems to be necessary (2.5.3 w/ MingW atleast)
- if ( item < -1 || item >= (int)m_strings.GetCount() )
- item = -1;
+ wxCHECK_RET( item == wxNOT_FOUND || ((unsigned int)item < GetCount()),
+ wxT("invalid index in wxVListBoxComboPopup::SetSelection") );
m_value = item;
wxVListBox::SetSelection(item);
}
+int wxVListBoxComboPopup::GetSelection() const
+{
+ return m_value;
+}
+
void wxVListBoxComboPopup::SetStringValue( const wxString& value )
{
int index = m_strings.Index(value);
height+2);
}
-void wxVListBoxComboPopup::Populate( int n, const wxString choices[] )
+//void wxVListBoxComboPopup::Populate( int n, const wxString choices[] )
+void wxVListBoxComboPopup::Populate( const wxArrayString& choices )
{
int i;
+ int n = choices.GetCount();
+
for ( i=0; i<n; i++ )
{
- const wxString& item = choices[i];
+ const wxString& item = choices.Item(i);
m_strings.Add(item);
CheckWidth(i);
}
// ----------------------------------------------------------------------------
-BEGIN_EVENT_TABLE(wxOwnerDrawnComboBox, wxComboControl)
+BEGIN_EVENT_TABLE(wxOwnerDrawnComboBox, wxComboCtrl)
END_EVENT_TABLE()
-IMPLEMENT_DYNAMIC_CLASS2(wxOwnerDrawnComboBox, wxComboControl, wxControlWithItems)
+IMPLEMENT_DYNAMIC_CLASS2(wxOwnerDrawnComboBox, wxComboCtrl, wxControlWithItems)
void wxOwnerDrawnComboBox::Init()
{
+ m_popupInterface = NULL;
}
bool wxOwnerDrawnComboBox::Create(wxWindow *parent,
const wxValidator& validator,
const wxString& name)
{
- return wxComboControl::Create(parent,id,value,pos,size,style,validator,name);
+ return wxComboCtrl::Create(parent,id,value,pos,size,style,validator,name);
}
wxOwnerDrawnComboBox::wxOwnerDrawnComboBox(wxWindow *parent,
long style,
const wxValidator& validator,
const wxString& name)
- : wxComboControl()
+ : wxComboCtrl()
{
Init();
const wxValidator& validator,
const wxString& name)
{
- wxCArrayString chs(choices);
+ m_initChs = choices;
+ //wxCArrayString chs(choices);
- return Create(parent, id, value, pos, size, chs.GetCount(),
- chs.GetStrings(), style, validator, name);
+ //return Create(parent, id, value, pos, size, chs.GetCount(),
+ // chs.GetStrings(), style, validator, name);
+ return Create(parent, id, value, pos, size, 0,
+ NULL, style, validator, name);
}
bool wxOwnerDrawnComboBox::Create(wxWindow *parent,
return false;
}
- wxVListBoxComboPopup* iface = new wxVListBoxComboPopup(this);
- SetPopupControl(iface);
-
- // m_popupInterface has been overridden as wxVListBoxComboPopup
- m_popupInterface = iface;
-
- // Add initial choices to the wxVListBox
- iface->Populate(n,choices);
+ int i;
+ for ( i=0; i<n; i++ )
+ m_initChs.Add(choices[i]);
return true;
}
m_popupInterface->ClearClientDatas();
}
+void wxOwnerDrawnComboBox::SetPopupControl( wxComboPopup* popup )
+{
+ if ( !popup )
+ {
+ popup = new wxVListBoxComboPopup();
+ }
+
+ wxComboCtrl::SetPopupControl(popup);
+
+ wxASSERT(popup);
+ m_popupInterface = (wxVListBoxComboPopup*) popup;
+
+ // Add initial choices to the wxVListBox
+ if ( !m_popupInterface->GetCount() )
+ {
+ //m_popupInterface->Populate(m_initChs.GetCount(),m_initChs.GetStrings());
+ m_popupInterface->Populate(m_initChs);
+ m_initChs.Clear();
+ }
+}
+
// ----------------------------------------------------------------------------
// wxOwnerDrawnComboBox item manipulation methods
// ----------------------------------------------------------------------------
void wxOwnerDrawnComboBox::Clear()
{
- wxASSERT( m_popupInterface );
+ EnsurePopupControl();
m_popupInterface->Clear();
- GetTextCtrl()->SetValue(wxEmptyString);
+ SetValue(wxEmptyString);
}
void wxOwnerDrawnComboBox::Delete(unsigned int n)
{
- wxCHECK_RET( (n >= 0) && (n < GetCount()), _T("invalid index in wxOwnerDrawnComboBox::Delete") );
+ wxCHECK_RET( IsValid(n), _T("invalid index in wxOwnerDrawnComboBox::Delete") );
if ( GetSelection() == (int) n )
SetValue(wxEmptyString);
unsigned int wxOwnerDrawnComboBox::GetCount() const
{
- wxASSERT( m_popupInterface );
+ wxASSERT_MSG( m_popupInterface, wxT("no popup interface") );
return m_popupInterface->GetCount();
}
wxString wxOwnerDrawnComboBox::GetString(unsigned int n) const
{
- wxCHECK_MSG( (n >= 0) && (n < GetCount()), wxEmptyString, _T("invalid index in wxOwnerDrawnComboBox::GetString") );
+ wxCHECK_MSG( IsValid(n), wxEmptyString, _T("invalid index in wxOwnerDrawnComboBox::GetString") );
return m_popupInterface->GetString(n);
}
void wxOwnerDrawnComboBox::SetString(unsigned int n, const wxString& s)
{
- wxCHECK_RET( (n >= 0) && (n < GetCount()), _T("invalid index in wxOwnerDrawnComboBox::SetString") );
+ wxCHECK_RET( IsValid(n), _T("invalid index in wxOwnerDrawnComboBox::SetString") );
m_popupInterface->SetString(n,s);
}
int wxOwnerDrawnComboBox::FindString(const wxString& s) const
{
- wxASSERT( m_popupInterface );
+ wxASSERT_MSG( m_popupInterface, wxT("no popup interface") );
return m_popupInterface->FindString(s);
}
void wxOwnerDrawnComboBox::Select(int n)
{
- wxCHECK_RET( (n >= -1) && (n < (int)GetCount()), _T("invalid index in wxOwnerDrawnComboBox::Select") );
- wxASSERT( m_popupInterface );
+ wxCHECK_RET( (n == wxNOT_FOUND) || IsValid(n), _T("invalid index in wxOwnerDrawnComboBox::Select") );
+ EnsurePopupControl();
m_popupInterface->SetSelection(n);
int wxOwnerDrawnComboBox::GetSelection() const
{
- wxASSERT( m_popupInterface );
+ wxASSERT_MSG( m_popupInterface, wxT("no popup interface") );
return m_popupInterface->GetSelection();
}
int wxOwnerDrawnComboBox::DoAppend(const wxString& item)
{
- wxASSERT( m_popupInterface );
+ EnsurePopupControl();
+ wxASSERT(m_popupInterface);
return m_popupInterface->Append(item);
}
int wxOwnerDrawnComboBox::DoInsert(const wxString& item, unsigned int pos)
{
wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list"));
- wxCHECK_MSG((pos>=0) && (pos<=GetCount()), -1, wxT("invalid index"));
+ wxCHECK_MSG(IsValidInsert(pos), -1, wxT("invalid index"));
+ EnsurePopupControl();
m_popupInterface->Insert(item,pos);
return pos;
void wxOwnerDrawnComboBox::DoSetItemClientData(unsigned int n, void* clientData)
{
- wxASSERT(m_popupInterface);
+ EnsurePopupControl();
m_popupInterface->SetItemClientData(n,clientData,m_clientDataItemsType);
}
void* wxOwnerDrawnComboBox::DoGetItemClientData(unsigned int n) const
{
- wxASSERT(m_popupInterface);
+ wxASSERT_MSG( m_popupInterface, wxT("no popup interface") );
return m_popupInterface->GetItemClientData(n);
}
return (wxClientData*) DoGetItemClientData(n);
}
-#endif // wxUSE_OWNERDRAWNCOMBOBOX
+#endif // wxUSE_ODCOMBOBOX