BEGIN_EVENT_TABLE(wxVListBoxComboPopup, wxVListBox)
EVT_MOTION(wxVListBoxComboPopup::OnMouseMove)
EVT_KEY_DOWN(wxVListBoxComboPopup::OnKey)
+ EVT_CHAR(wxVListBoxComboPopup::OnChar)
EVT_LEFT_UP(wxVListBoxComboPopup::OnLeftClick)
END_EVENT_TABLE()
Clear();
}
+void wxVListBoxComboPopup::SetFocus()
+{
+ // Suppress SetFocus() warning by simply not calling it. This combo popup
+ // has already been designed with the assumption that SetFocus() may not
+ // do anything useful, so it really doesn't need to be called.
+#ifdef __WXMSW__
+ //
+#else
+ wxVListBox::SetFocus();
+#endif
+}
+
bool wxVListBoxComboPopup::LazyCreate()
{
// NB: There is a bug with wxVListBox that can be avoided by creating
}
// returns true if key was consumed
-bool wxVListBoxComboPopup::HandleKey( int keycode, bool saturate, wxChar unicode )
+bool wxVListBoxComboPopup::HandleKey( int keycode, bool saturate, wxChar keychar )
{
const int itemCount = GetCount();
int value = m_value;
int comboStyle = m_combo->GetWindowStyle();
- // this is the character equivalent of the code
- wxChar keychar=0;
- if ((keycode >= WXK_SPACE) && (keycode <=255) && (keycode != WXK_DELETE) && wxIsprint(keycode))
- {
- keychar = (wxChar)keycode;
- }
- else if (unicode>0)
+ if ( keychar > 0 )
{
- keychar = unicode;
+ // we have character equivalent of the keycode; filter out these that
+ // are not printable characters
+ if ( !wxIsprint(keychar) )
+ keychar = 0;
}
- if ( keycode == WXK_DOWN || keycode == WXK_RIGHT )
+ if ( keycode == WXK_DOWN || keycode == WXK_NUMPAD_DOWN || keycode == WXK_RIGHT )
{
value++;
StopPartialCompletion();
}
- else if ( keycode == WXK_UP || keycode == WXK_LEFT )
+ else if ( keycode == WXK_UP || keycode == WXK_NUMPAD_UP || keycode == WXK_LEFT )
{
value--;
StopPartialCompletion();
}
- else if ( keycode == WXK_PAGEDOWN )
+ else if ( keycode == WXK_PAGEDOWN || keycode == WXK_NUMPAD_PAGEDOWN )
{
value+=10;
StopPartialCompletion();
}
- else if ( keycode == WXK_PAGEUP )
+ else if ( keycode == WXK_PAGEUP || keycode == WXK_NUMPAD_PAGEUP )
{
value-=10;
StopPartialCompletion();
}
- else if ( comboStyle & wxCB_READONLY )
+ else if ( keycode == WXK_HOME || keycode == WXK_NUMPAD_HOME )
+ {
+ value=0;
+ StopPartialCompletion();
+ }
+ else if ( keycode == WXK_END || keycode == WXK_NUMPAD_END )
+ {
+ value=itemCount-1;
+ StopPartialCompletion();
+ }
+ else if ( keychar && (comboStyle & wxCB_READONLY) )
{
// Try partial completion
// (good for consistency)
return true;
- m_value = value;
-
if ( value >= 0 )
m_combo->SetValue(m_strings[value]);
+ // The m_combo->SetValue() call above sets m_value to the index of this
+ // string. But if there are more identical string, the index is of the
+ // first occurence, which may be wrong, so set the index explicitly here,
+ // _after_ the SetValue() call.
+ m_value = value;
+
SendComboBoxEvent(m_value);
return true;
void wxVListBoxComboPopup::OnComboKeyEvent( wxKeyEvent& event )
{
// Saturated key movement on
- if ( !HandleKey(event.GetKeyCode(),true,
+ if ( !HandleKey(event.GetKeyCode(), true) )
+ event.Skip();
+}
+
+void wxVListBoxComboPopup::OnComboCharEvent( wxKeyEvent& event )
+{
+ // unlike in OnComboKeyEvent, wxEVT_CHAR contains meaningful
+ // printable character information, so pass it
#if wxUSE_UNICODE
- event.GetUnicodeKey()
+ const wxChar charcode = event.GetUnicodeKey();
#else
- 0
+ const wxChar charcode = (wxChar)event.GetKeyCode();
#endif
- ) )
+
+ if ( !HandleKey(event.GetKeyCode(), true, charcode) )
event.Skip();
}
}
else
{
- int comboStyle = m_combo->GetWindowStyle();
- int keycode = event.GetKeyCode();
- // Process partial completion key codes here, but not the arrow keys as the base class will do that for us
- if ((comboStyle & wxCB_READONLY) &&
- (keycode >= WXK_SPACE) && (keycode <=255) && (keycode != WXK_DELETE) && wxIsprint(keycode))
+ // completion is handled in OnChar() below
+ event.Skip();
+ }
+}
+
+void wxVListBoxComboPopup::OnChar(wxKeyEvent& event)
+{
+ if ( m_combo->GetWindowStyle() & wxCB_READONLY )
+ {
+ // Process partial completion key codes here, but not the arrow keys as
+ // the base class will do that for us
+#if wxUSE_UNICODE
+ const wxChar charcode = event.GetUnicodeKey();
+#else
+ const wxChar charcode = (wxChar)event.GetKeyCode();
+#endif
+ if ( wxIsprint(charcode) )
{
- OnComboKeyEvent(event);
+ OnComboCharEvent(event);
SetSelection(m_value); // ensure the highlight bar moves
+ return; // don't skip the event
}
- else
- event.Skip();
}
+
+ event.Skip();
}
void wxVListBoxComboPopup::Insert( const wxString& item, int pos )
}
m_strings.Insert(item,pos);
- m_clientDatas.Insert(NULL, pos);
+ if ( (int)m_clientDatas.size() >= pos )
+ m_clientDatas.Insert(NULL, pos);
m_widths.Insert(-1,pos);
m_widthsDirty = true;
for ( i=0; i<strings.GetCount(); i++ )
{
- if ( item.Cmp(strings.Item(i)) < 0 )
+ if ( item.CmpNoCase(strings.Item(i)) < 0 )
{
pos = (int)i;
break;
height = maxHeight;
int totalHeight = GetTotalHeight(); // + 3;
+
+ // Take borders into account on Mac or scrollbars always appear
+#if defined(__WXMAC__)
+ totalHeight += 2;
+#endif
if ( height >= totalHeight )
{
height = totalHeight;
void wxOwnerDrawnComboBox::DoDeleteOneItem(unsigned int n)
{
- wxCHECK_RET( IsValid(n), _T("invalid index in wxOwnerDrawnComboBox::Delete") );
+ wxCHECK_RET( IsValid(n), wxT("invalid index in wxOwnerDrawnComboBox::Delete") );
if ( GetSelection() == (int) n )
SetValue(wxEmptyString);
wxString wxOwnerDrawnComboBox::GetString(unsigned int n) const
{
- wxCHECK_MSG( IsValid(n), wxEmptyString, _T("invalid index in wxOwnerDrawnComboBox::GetString") );
+ wxCHECK_MSG( IsValid(n), wxEmptyString, wxT("invalid index in wxOwnerDrawnComboBox::GetString") );
if ( !m_popupInterface )
return m_initChs.Item(n);
{
EnsurePopupControl();
- wxCHECK_RET( IsValid(n), _T("invalid index in wxOwnerDrawnComboBox::SetString") );
+ wxCHECK_RET( IsValid(n), wxT("invalid index in wxOwnerDrawnComboBox::SetString") );
GetVListBoxComboPopup()->SetString(n,s);
}
{
EnsurePopupControl();
- wxCHECK_RET( (n == wxNOT_FOUND) || IsValid(n), _T("invalid index in wxOwnerDrawnComboBox::Select") );
+ wxCHECK_RET( (n == wxNOT_FOUND) || IsValid(n), wxT("invalid index in wxOwnerDrawnComboBox::Select") );
GetVListBoxComboPopup()->SetSelection(n);
EnsurePopupControl();
const unsigned int count = items.GetCount();
- for( unsigned int i = 0; i < count; ++i, ++pos )
+
+ if ( HasFlag(wxCB_SORT) )
{
- GetVListBoxComboPopup()->Insert(items[i], pos);
- AssignNewItemClientData(pos, clientData, i, type);
+ int n = pos;
+
+ for ( unsigned int i = 0; i < count; ++i )
+ {
+ n = GetVListBoxComboPopup()->Append(items[i]);
+ AssignNewItemClientData(n, clientData, i, type);
+ }
+
+ return n;
}
+ else
+ {
+ for ( unsigned int i = 0; i < count; ++i, ++pos )
+ {
+ GetVListBoxComboPopup()->Insert(items[i], pos);
+ AssignNewItemClientData(pos, clientData, i, type);
+ }
- return pos - 1;
+ return pos - 1;
+ }
}
void wxOwnerDrawnComboBox::DoSetItemClientData(unsigned int n, void* clientData)
{
if ( flags & wxODCB_PAINTING_CONTROL )
{
- dc.DrawText( GetValue(),
- rect.x + GetTextIndent(),
+ wxString text;
+
+ if ( !ShouldUseHintText() )
+ {
+ text = GetValue();
+ }
+ else
+ {
+ text = GetHint();
+ wxColour col = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT);
+ dc.SetTextForeground(col);
+ }
+
+ dc.DrawText( text,
+ rect.x + GetMargins().x,
(rect.height-dc.GetCharHeight())/2 + rect.y );
}
else