X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d69225772ad1ff3952a3ee74055dc93f85c13812..64ea838d8f4d1853b7d850db93ee565e901d099a:/src/univ/combobox.cpp diff --git a/src/univ/combobox.cpp b/src/univ/combobox.cpp index 5c751f5aa9..e41adaa761 100644 --- a/src/univ/combobox.cpp +++ b/src/univ/combobox.cpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: univ/combobox.cpp -// Purpose: wxComboControl and wxComboBox implementation +// Name: src/univ/combobox.cpp +// Purpose: wxComboBox implementation // Author: Vadim Zeitlin // Modified by: // Created: 15.12.00 @@ -17,10 +17,6 @@ // headers // ---------------------------------------------------------------------------- -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) - #pragma implementation "univcombobox.h" -#endif - #include "wx/wxprec.h" #ifdef __BORLANDC__ @@ -42,71 +38,24 @@ #endif #include "wx/tooltip.h" -#include "wx/popupwin.h" +#include "wx/combo.h" #include "wx/univ/renderer.h" #include "wx/univ/inphand.h" #include "wx/univ/theme.h" -/* - The keyboard event flow: - - 1. they always come to the text ctrl - 2. it forwards the ones it doesn't process to the wxComboControl - 3. which passes them to the popup window if it is popped up - */ - -// constants // ---------------------------------------------------------------------------- - -// the margin between the text control and the combo button -static const wxCoord g_comboMargin = 2; - -// ---------------------------------------------------------------------------- -// wxComboButton is just a normal button except that it sends commands to the -// combobox and not its parent +// wxStdComboBoxInputHandler: allows the user to open/close the combo from kbd // ---------------------------------------------------------------------------- -class wxComboButton : public wxBitmapButton +class WXDLLEXPORT wxStdComboBoxInputHandler : public wxStdInputHandler { public: - wxComboButton(wxComboControl *combo) - : wxBitmapButton(combo->GetParent(), wxID_ANY, wxNullBitmap, - wxDefaultPosition, wxDefaultSize, - wxBORDER_NONE | wxBU_EXACTFIT) - { - m_combo = combo; + wxStdComboBoxInputHandler(wxInputHandler *inphand); - wxBitmap bmpNormal, bmpFocus, bmpPressed, bmpDisabled; - - GetRenderer()->GetComboBitmaps(&bmpNormal, - &bmpFocus, - &bmpPressed, - &bmpDisabled); - - SetBitmapLabel(bmpNormal); - SetBitmapFocus(bmpFocus.Ok() ? bmpFocus : bmpNormal); - SetBitmapSelected(bmpPressed.Ok() ? bmpPressed : bmpNormal); - SetBitmapDisabled(bmpDisabled.Ok() ? bmpDisabled : bmpNormal); - - SetBestSize(wxDefaultSize); - } - -protected: - void OnButton(wxCommandEvent& WXUNUSED(event)) { m_combo->ShowPopup(); } - - virtual wxSize DoGetBestClientSize() const - { - const wxBitmap& bmp = GetBitmapLabel(); - - return wxSize(bmp.GetWidth(), bmp.GetHeight()); - - } - -private: - wxComboControl *m_combo; - - DECLARE_EVENT_TABLE() + virtual bool HandleKey(wxInputConsumer *consumer, + const wxKeyEvent& event, + bool pressed); }; // ---------------------------------------------------------------------------- @@ -118,63 +67,32 @@ class wxComboListBox : public wxListBox, public wxComboPopup { public: // ctor and dtor - wxComboListBox(wxComboControl *combo, int style = 0); + wxComboListBox(); virtual ~wxComboListBox(); // implement wxComboPopup methods - virtual bool SetSelection(const wxString& s); - virtual wxControl *GetControl() { return this; } - virtual void OnShow(); - virtual wxCoord GetBestWidth() const; + virtual bool Create(wxWindow* parent); + virtual void SetStringValue(const wxString& s); + virtual wxString GetStringValue() const; + virtual wxWindow *GetControl() { return this; } + virtual void OnPopup(); + virtual wxSize GetAdjustedSize(int minWidth, int prefHeight, int maxHeight); // fix virtual function hiding virtual void SetSelection(int n) { DoSetSelection(n, true); } void SetSelection(int n, bool select) { DoSetSelection(n, select); } -protected: - // we shouldn't return height too big from here - virtual wxSize DoGetBestClientSize() const; - - // filter mouse move events happening outside the list box - void OnMouseMove(wxMouseEvent& event); - - // set m_clicked value from here - void OnLeftUp(wxMouseEvent& event); - - // called whenever the user selects or activates a listbox item - void OnSelect(wxCommandEvent& event); - // used to process wxUniv actions bool PerformAction(const wxControlAction& action, long numArg, const wxString& strArg); -private: - // has the mouse been released on this control? - bool m_clicked; - - DECLARE_EVENT_TABLE() -}; - -// ---------------------------------------------------------------------------- -// wxComboTextCtrl is a simple text ctrl which forwards -// wxEVT_COMMAND_TEXT_UPDATED events and all key events to the combobox -// ---------------------------------------------------------------------------- - -class wxComboTextCtrl : public wxTextCtrl -{ -public: - wxComboTextCtrl(wxComboControl *combo, - const wxString& value, - long style, - const wxValidator& validator); - protected: - void OnKey(wxKeyEvent& event); - void OnText(wxCommandEvent& event); + // set m_clicked value from here + void OnLeftUp(wxMouseEvent& event); private: - wxComboControl *m_combo; + friend class wxComboBox; // it accesses our DoGetItemClientData() DECLARE_EVENT_TABLE() }; @@ -183,406 +101,59 @@ private: // event tables and such // ---------------------------------------------------------------------------- -BEGIN_EVENT_TABLE(wxComboButton, wxButton) - EVT_BUTTON(wxID_ANY, wxComboButton::OnButton) -END_EVENT_TABLE() - BEGIN_EVENT_TABLE(wxComboListBox, wxListBox) - EVT_LISTBOX(wxID_ANY, wxComboListBox::OnSelect) - EVT_LISTBOX_DCLICK(wxID_ANY, wxComboListBox::OnSelect) - EVT_MOTION(wxComboListBox::OnMouseMove) EVT_LEFT_UP(wxComboListBox::OnLeftUp) END_EVENT_TABLE() -BEGIN_EVENT_TABLE(wxComboControl, wxControl) - EVT_KEY_DOWN(wxComboControl::OnKey) - EVT_KEY_UP(wxComboControl::OnKey) -END_EVENT_TABLE() - -BEGIN_EVENT_TABLE(wxComboTextCtrl, wxTextCtrl) - EVT_KEY_DOWN(wxComboTextCtrl::OnKey) - EVT_KEY_UP(wxComboTextCtrl::OnKey) - EVT_TEXT(wxID_ANY, wxComboTextCtrl::OnText) -END_EVENT_TABLE() - -IMPLEMENT_DYNAMIC_CLASS(wxComboBox, wxControl) - // ============================================================================ // implementation // ============================================================================ // ---------------------------------------------------------------------------- -// wxComboControl creation -// ---------------------------------------------------------------------------- - -void wxComboControl::Init() -{ - m_popup = (wxComboPopup *)NULL; - m_winPopup = (wxPopupComboWindow *)NULL; - m_isPopupShown = false; - m_btn = NULL; - m_text = NULL; -} - -bool wxComboControl::Create(wxWindow *parent, - wxWindowID id, - const wxString& value, - const wxPoint& pos, - const wxSize& size, - long style, - const wxValidator& validator, - const wxString& name) -{ - // first create our own window, i.e. the one which will contain all - // subcontrols - style &= ~wxBORDER_NONE; - style |= wxBORDER_SUNKEN; - if ( !wxControl::Create(parent, id, pos, size, style, validator, name) ) - return false; - - // create the text control and the button as our siblings (*not* children), - // don't care about size/position here - they will be set in DoMoveWindow() - m_btn = new wxComboButton(this); - m_text = new wxComboTextCtrl(this, - value, - style & wxCB_READONLY ? wxTE_READONLY : 0, - validator); - - // for compatibility with the other ports, the height specified is the - // combined height of the combobox itself and the popup - if ( size.y == wxDefaultCoord ) - { - // ok, use default height for popup too - m_heightPopup = wxDefaultCoord; - } - else - { - m_heightPopup = size.y - DoGetBestSize().y; - } - - SetBestSize(size); - Move(pos); - - // create the popup window immediately here to allow creating the controls - // with parent == GetPopupWindow() from the derived class ctor - m_winPopup = new wxPopupComboWindow(this); - - // have to disable this window to avoid interfering it with message - // processing to the text and the button... but pretend it is enabled to - // make IsEnabled() return true - wxControl::Enable(false); // don't use non virtual Disable() here! - m_isEnabled = true; - - CreateInputHandler(wxINP_HANDLER_COMBOBOX); - - return true; -} - -wxComboControl::~wxComboControl() -{ - // as the button and the text control are the parent's children and not - // ours, we have to delete them manually - they are not deleted - // automatically by wxWidgets when we're deleted - delete m_btn; - delete m_text; - - delete m_winPopup; -} - -// ---------------------------------------------------------------------------- -// geometry stuff -// ---------------------------------------------------------------------------- - -void wxComboControl::DoSetSize(int x, int y, - int width, int WXUNUSED(height), - int sizeFlags) -{ - // combo height is always fixed - wxControl::DoSetSize(x, y, width, DoGetBestSize().y, sizeFlags); -} - -wxSize wxComboControl::DoGetBestClientSize() const -{ - wxSize sizeBtn = m_btn->GetBestSize(), - sizeText = m_text->GetBestSize(); - wxCoord widthPopup = 0; - - if (m_popup) - { - widthPopup = m_popup->GetBestWidth(); - } - - return wxSize(wxMax(sizeText.x + g_comboMargin + sizeBtn.x, widthPopup), - wxMax(sizeBtn.y, sizeText.y)); -} - -void wxComboControl::DoMoveWindow(int x, int y, int width, int height) -{ - wxControl::DoMoveWindow(x, y, width, height); - - // position the subcontrols inside the client area - wxRect rectBorders = GetRenderer()->GetBorderDimensions(GetBorder()); - x += rectBorders.x; - y += rectBorders.y; - width -= rectBorders.x + rectBorders.width; - height -= rectBorders.y + rectBorders.height; - - wxSize sizeBtn = m_btn->GetBestSize(); - - wxCoord wText = width - sizeBtn.x; - wxPoint p = GetParent() ? GetParent()->GetClientAreaOrigin() : wxPoint(0,0); - m_text->SetSize(x - p.x, y - p.y, wText, height); - m_btn->SetSize(x - p.x + wText, y - p.y, sizeBtn.x, height); -} - -// ---------------------------------------------------------------------------- -// operations -// ---------------------------------------------------------------------------- - -bool wxComboControl::Enable(bool enable) -{ - if ( !wxControl::Enable(enable) ) - return false; - - m_btn->Enable(enable); - m_text->Enable(enable); - - return true; -} - -bool wxComboControl::Show(bool show) -{ - if ( !wxControl::Show(show) ) - return false; - - if (m_btn) - m_btn->Show(show); - - if (m_text) - m_text->Show(show); - - return true; -} - -#if wxUSE_TOOLTIPS -void wxComboControl::DoSetToolTip(wxToolTip *tooltip) -{ - wxControl::DoSetToolTip(tooltip); - - // Set tool tip for button and text box - if (m_text && m_btn) - { - if (tooltip) - { - const wxString &tip = tooltip->GetTip(); - m_text->SetToolTip(tip); - m_btn->SetToolTip(tip); - } - else - { - m_text->SetToolTip(NULL); - m_btn->SetToolTip(NULL); - } - } -} -#endif // wxUSE_TOOLTIPS - -// ---------------------------------------------------------------------------- -// popup window handling +// wxComboListBox // ---------------------------------------------------------------------------- -void wxComboControl::SetPopupControl(wxComboPopup *popup) +wxComboListBox::wxComboListBox() : wxListBox(), wxComboPopup() { - m_popup = popup; } -void wxComboControl::ShowPopup() +bool wxComboListBox::Create(wxWindow* parent) { - wxCHECK_RET( m_popup, _T("no popup to show in wxComboControl") ); - wxCHECK_RET( !IsPopupShown(), _T("popup window already shown") ); - - wxControl *control = m_popup->GetControl(); - - // size and position the popup window correctly - m_winPopup->SetSize(GetSize().x, - m_heightPopup == wxDefaultCoord ? control->GetBestSize().y - : m_heightPopup); - wxSize sizePopup = m_winPopup->GetClientSize(); - control->SetSize(0, 0, sizePopup.x, sizePopup.y); - - // some controls don't accept the size we give then: e.g. a listbox may - // require more space to show its last row - wxSize sizeReal = control->GetSize(); - if ( sizeReal != sizePopup ) - { - m_winPopup->SetClientSize(sizeReal); - } - - m_winPopup->PositionNearCombo(); - - // show it - m_popup->OnShow(); - m_winPopup->Popup(m_text); - m_text->SelectAll(); - m_popup->SetSelection(m_text->GetValue()); - - m_isPopupShown = true; -} - -void wxComboControl::HidePopup() -{ - wxCHECK_RET( m_popup, _T("no popup to hide in wxComboControl") ); - wxCHECK_RET( IsPopupShown(), _T("popup window not shown") ); - - m_winPopup->Dismiss(); - - m_isPopupShown = false; -} - -void wxComboControl::OnSelect(const wxString& value) -{ - m_text->SetValue(value); - m_text->SelectAll(); - - OnDismiss(); -} - -void wxComboControl::OnDismiss() -{ - HidePopup(); - m_text->SetFocus(); -} - -// ---------------------------------------------------------------------------- -// wxComboTextCtrl -// ---------------------------------------------------------------------------- - -wxComboTextCtrl::wxComboTextCtrl(wxComboControl *combo, - const wxString& value, - long style, - const wxValidator& validator) - : wxTextCtrl(combo->GetParent(), wxID_ANY, value, + if ( !wxListBox::Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, - wxBORDER_NONE | style, - validator) -{ - m_combo = combo; -} - -void wxComboTextCtrl::OnText(wxCommandEvent& event) -{ - if ( m_combo->IsPopupShown() ) - { - m_combo->GetPopupControl()->SetSelection(GetValue()); - } - - // we need to make a copy of the event to have the correct originating - // object and id - wxCommandEvent event2 = event; - event2.SetEventObject(m_combo); - event2.SetId(m_combo->GetId()); - - // there is a small incompatibility with wxMSW here: the combobox gets the - // event before the text control in our case which corresponds to SMW - // CBN_EDITUPDATE notification and not CBN_EDITCHANGE one wxMSW currently - // uses - // - // if this is really a problem, we can play games with the event handlers - // to circumvent this - (void)m_combo->ProcessEvent(event2); - - event.Skip(); -} - -// pass the keys we don't process to the combo first -void wxComboTextCtrl::OnKey(wxKeyEvent& event) -{ - switch ( event.GetKeyCode() ) - { - case WXK_RETURN: - // the popup control gets it first but only if it is shown - if ( !m_combo->IsPopupShown() ) - break; - //else: fall through - - case WXK_UP: - case WXK_DOWN: - case WXK_ESCAPE: - case WXK_PAGEDOWN: - case WXK_PAGEUP: - case WXK_PRIOR: - case WXK_NEXT: - (void)m_combo->ProcessEvent(event); - return; - } - - event.Skip(); -} - -// ---------------------------------------------------------------------------- -// wxComboListBox -// ---------------------------------------------------------------------------- + 0, NULL, + wxBORDER_SIMPLE | + ( m_combo->GetWindowStyle() & wxCB_SORT ? wxLB_SORT : 0 ) ) ) + return false; -wxComboListBox::wxComboListBox(wxComboControl *combo, int style) - : wxListBox(combo->GetPopupWindow(), wxID_ANY, - wxDefaultPosition, wxDefaultSize, - 0, NULL, - wxBORDER_SIMPLE | wxLB_INT_HEIGHT | style), - wxComboPopup(combo) -{ // we don't react to the mouse events outside the window at all StopAutoScrolling(); + + return true; } wxComboListBox::~wxComboListBox() { } -bool wxComboListBox::SetSelection(const wxString& value) +wxString wxComboListBox::GetStringValue() const { - // FindItem() would just find the current item for an empty string (it - // always matches), but we want to show the first one in such case - if ( value.empty() ) - { - if ( GetCount() ) - { - wxListBox::SetSelection(0); - } - //else: empty listbox - nothing to do - } - else if ( !FindItem(value) ) - { - // no match att all - return false; - } - - return true; + return wxListBox::GetStringSelection(); } -void wxComboListBox::OnSelect(wxCommandEvent& event) +void wxComboListBox::SetStringValue(const wxString& value) { - if ( m_clicked ) + if ( !value.empty() ) { - // first update the combo and close the listbox - m_combo->OnSelect(event.GetString()); - - // next let the user code have the event - - // all fields are already filled by the listbox, just change the event - // type and send it to the combo - wxCommandEvent event2 = event; - event2.SetEventType(wxEVT_COMMAND_COMBOBOX_SELECTED); - event2.SetEventObject(m_combo); - event2.SetId(m_combo->GetId()); - m_combo->ProcessEvent(event2); + if (FindString(value) != wxNOT_FOUND) + wxListBox::SetStringSelection(value); } - //else: ignore the events resulting from just moving the mouse initially + else + wxListBox::SetSelection(-1); } -void wxComboListBox::OnShow() +void wxComboListBox::OnPopup() { - // nobody clicked us yet - m_clicked = false; } bool wxComboListBox::PerformAction(const wxControlAction& action, @@ -594,7 +165,7 @@ bool wxComboListBox::PerformAction(const wxControlAction& action, { // we don't let the listbox handle this as instead of just using the // single key presses, as usual, we use the text ctrl value as prefix - // and this is done by wxComboControl itself + // and this is done by wxComboCtrl itself return true; } @@ -604,50 +175,26 @@ bool wxComboListBox::PerformAction(const wxControlAction& action, void wxComboListBox::OnLeftUp(wxMouseEvent& event) { // we should dismiss the combo now - m_clicked = true; + // first update the combo and close the listbox + Dismiss(); + m_combo->SetValue(wxListBox::GetStringSelection()); - event.Skip(); -} + // next let the user code have the event + wxCommandEvent evt(wxEVT_COMMAND_COMBOBOX_SELECTED,m_combo->GetId()); + evt.SetInt(wxListBox::GetSelection()); + evt.SetEventObject(m_combo); + m_combo->ProcessWindowEvent(evt); -void wxComboListBox::OnMouseMove(wxMouseEvent& event) -{ - // while a wxComboListBox is shown, it always has capture, so if it doesn't - // we're about to go away anyhow (normally this shouldn't happen at all, - // but I don't put assert here as it just might do on other platforms and - // it doesn't break anything anyhow) - if ( this == wxWindow::GetCapture() ) - { - if ( HitTest(event.GetPosition()) == wxHT_WINDOW_INSIDE ) - { - event.Skip(); - } - //else: popup shouldn't react to the mouse motions outside it, it only - // captures the mouse to be able to detect when it must be - // dismissed, so don't call Skip() - } -} - -wxCoord wxComboListBox::GetBestWidth() const -{ - wxSize size = wxListBox::GetBestSize(); - return size.x; + event.Skip(); } -wxSize wxComboListBox::DoGetBestClientSize() const +wxSize wxComboListBox::GetAdjustedSize(int minWidth, + int WXUNUSED(prefHeight), + int maxHeight) { - // don't return size too big or we risk to not fit on the screen - wxSize size = wxListBox::DoGetBestClientSize(); - wxCoord hChar = GetCharHeight(); - - int nLines = size.y / hChar; - - // 10 is the same limit as used by wxMSW - if ( nLines > 10 ) - { - size.y = 10*hChar; - } - - return size; + wxSize bestSize = wxListBox::GetBestSize(); + return wxSize(wxMax(bestSize.x,minWidth), + wxMin(bestSize.y,maxHeight)); } // ---------------------------------------------------------------------------- @@ -656,7 +203,7 @@ wxSize wxComboListBox::DoGetBestClientSize() const void wxComboBox::Init() { - m_lbox = (wxListBox *)NULL; + m_lbox = NULL; } wxComboBox::wxComboBox(wxWindow *parent, @@ -701,19 +248,18 @@ bool wxComboBox::Create(wxWindow *parent, const wxValidator& validator, const wxString& name) { - if ( !wxComboControl::Create(parent, id, value, pos, size, style, + if ( !wxComboCtrl::Create(parent, id, value, pos, size, style, validator, name) ) { return false; } - wxComboListBox *combolbox = - new wxComboListBox(this, style & wxCB_SORT ? wxLB_SORT : 0); + wxComboListBox *combolbox = new wxComboListBox(); + SetPopupControl(combolbox); + m_lbox = combolbox; m_lbox->Set(n, choices); - SetPopupControl(combolbox); - return true; } @@ -725,207 +271,224 @@ wxComboBox::~wxComboBox() // wxComboBox methods forwarded to wxTextCtrl // ---------------------------------------------------------------------------- -wxString wxComboBox::GetValue() const +wxString wxComboBox::DoGetValue() const { - return GetText()->GetValue(); + return GetTextCtrl() ? GetTextCtrl()->GetValue() : m_valueString; } void wxComboBox::SetValue(const wxString& value) { - GetText()->SetValue(value); + if ( GetTextCtrl() ) + GetTextCtrl()->SetValue(value); + else + m_valueString = value; +} + +void wxComboBox::WriteText(const wxString& value) +{ + if ( GetTextCtrl() ) GetTextCtrl()->WriteText(value); } void wxComboBox::Copy() { - GetText()->Copy(); + if ( GetTextCtrl() ) GetTextCtrl()->Copy(); } void wxComboBox::Cut() { - GetText()->Cut(); + if ( GetTextCtrl() ) GetTextCtrl()->Cut(); } void wxComboBox::Paste() { - GetText()->Paste(); + if ( GetTextCtrl() ) GetTextCtrl()->Paste(); } void wxComboBox::SetInsertionPoint(long pos) { - GetText()->SetInsertionPoint(pos); + if ( GetTextCtrl() ) GetTextCtrl()->SetInsertionPoint(pos); } void wxComboBox::SetInsertionPointEnd() { - GetText()->SetInsertionPointEnd(); + if ( GetTextCtrl() ) GetTextCtrl()->SetInsertionPointEnd(); } long wxComboBox::GetInsertionPoint() const { - return GetText()->GetInsertionPoint(); + if ( GetTextCtrl() ) + return GetTextCtrl()->GetInsertionPoint(); + return -1; } wxTextPos wxComboBox::GetLastPosition() const { - return GetText()->GetLastPosition(); + if ( GetTextCtrl() ) + return GetTextCtrl()->GetLastPosition(); + return -1; } void wxComboBox::Replace(long from, long to, const wxString& value) { - GetText()->Replace(from, to, value); + if ( GetTextCtrl() ) GetTextCtrl()->Replace(from, to, value); } void wxComboBox::Remove(long from, long to) { - GetText()->Remove(from, to); + if ( GetTextCtrl() ) GetTextCtrl()->Remove(from, to); } void wxComboBox::SetSelection(long from, long to) { - GetText()->SetSelection(from, to); + if ( GetTextCtrl() ) GetTextCtrl()->SetSelection(from, to); +} + +void wxComboBox::GetSelection(long *from, long *to) const +{ + if ( GetTextCtrl() ) GetTextCtrl()->GetSelection(from, to); } void wxComboBox::SetEditable(bool editable) { - GetText()->SetEditable(editable); + if ( GetTextCtrl() ) GetTextCtrl()->SetEditable(editable); } // ---------------------------------------------------------------------------- // wxComboBox methods forwarded to wxListBox // ---------------------------------------------------------------------------- -void wxComboBox::Clear() +void wxComboBox::DoClear() { GetLBox()->Clear(); - GetText()->SetValue(wxEmptyString); + SetValue(wxEmptyString); } -void wxComboBox::Delete(int n) +void wxComboBox::DoDeleteOneItem(unsigned int n) { - wxCHECK_RET( (n >= 0) && (n < GetCount()), _T("invalid index in wxComboBox::Delete") ); + wxCHECK_RET( IsValid(n), wxT("invalid index in wxComboBox::Delete") ); - if (GetSelection() == n) - GetText()->SetValue(wxEmptyString); + if (GetSelection() == (int)n) + SetValue(wxEmptyString); GetLBox()->Delete(n); } -int wxComboBox::GetCount() const +unsigned int wxComboBox::GetCount() const { return GetLBox()->GetCount(); } -wxString wxComboBox::GetString(int n) const +wxString wxComboBox::GetString(unsigned int n) const { - wxCHECK_MSG( (n >= 0) && (n < GetCount()), wxEmptyString, _T("invalid index in wxComboBox::GetString") ); + wxCHECK_MSG( IsValid(n), wxEmptyString, wxT("invalid index in wxComboBox::GetString") ); return GetLBox()->GetString(n); } -void wxComboBox::SetString(int n, const wxString& s) +void wxComboBox::SetString(unsigned int n, const wxString& s) { - wxCHECK_RET( (n >= 0) && (n < GetCount()), _T("invalid index in wxComboBox::SetString") ); + wxCHECK_RET( IsValid(n), wxT("invalid index in wxComboBox::SetString") ); GetLBox()->SetString(n, s); } -int wxComboBox::FindString(const wxString& s) const +int wxComboBox::FindString(const wxString& s, bool bCase) const { - return GetLBox()->FindString(s); + return GetLBox()->FindString(s, bCase); } void wxComboBox::SetSelection(int n) { - wxCHECK_RET( (n >= 0) && (n < GetCount()), _T("invalid index in wxComboBox::Select") ); + wxCHECK_RET( (n == wxNOT_FOUND || IsValid(n)), wxT("invalid index in wxComboBox::Select") ); GetLBox()->SetSelection(n); - GetText()->SetValue(GetLBox()->GetString(n)); + + wxString str; + if ( n != wxNOT_FOUND ) + str = GetLBox()->GetString(n); + + SetText(str); } int wxComboBox::GetSelection() const { -#if 1 // FIXME:: What is the correct behavior? +#if 1 // FIXME:: What is the correct behaviour? // if the current value isn't one of the listbox strings, return -1 return GetLBox()->GetSelection(); #else // Why oh why is this done this way? // It is not because the value displayed in the text can be found // in the list that it is the item that is selected! - return FindString(GetText()->GetValue()); + return FindString(if ( GetTextCtrl() ) GetTextCtrl()->GetValue()); #endif } -int wxComboBox::DoAppend(const wxString& item) +wxString wxComboBox::GetStringSelection() const { - return GetLBox()->Append(item); + return GetLBox()->GetStringSelection(); } -int wxComboBox::DoInsert(const wxString& item, int pos) +wxClientDataType wxComboBox::GetClientDataType() const { - wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list")); - wxCHECK_MSG((pos>=0) && (pos<=GetCount()), -1, wxT("invalid index")); - - if (pos == GetCount()) - return DoAppend(item); - - GetLBox()->Insert(item, pos); - return pos; + return GetLBox()->GetClientDataType(); } -void wxComboBox::DoSetItemClientData(int n, void* clientData) +void wxComboBox::SetClientDataType(wxClientDataType clientDataItemsType) { - GetLBox()->SetClientData(n, clientData); + GetLBox()->SetClientDataType(clientDataItemsType); } -void *wxComboBox::DoGetItemClientData(int n) const +int wxComboBox::DoInsertItems(const wxArrayStringsAdapter & items, + unsigned int pos, + void **clientData, wxClientDataType type) { - return GetLBox()->GetClientData(n); + return GetLBox()->DoInsertItems(items, pos, clientData, type); } -void wxComboBox::DoSetItemClientObject(int n, wxClientData* clientData) +void wxComboBox::DoSetItemClientData(unsigned int n, void* clientData) { - GetLBox()->SetClientObject(n, clientData); + GetLBox()->DoSetItemClientData(n, clientData); } -wxClientData* wxComboBox::DoGetItemClientObject(int n) const +void *wxComboBox::DoGetItemClientData(unsigned int n) const { - return GetLBox()->GetClientObject(n); + return GetLBox()->DoGetItemClientData(n); } bool wxComboBox::IsEditable() const { - return GetText() != NULL && (!HasFlag(wxCB_READONLY) || GetText()->IsEditable()); + return GetTextCtrl() != NULL && (!HasFlag(wxCB_READONLY) || GetTextCtrl()->IsEditable() ); } void wxComboBox::Undo() { if (IsEditable()) - GetText()->Undo(); + if ( GetTextCtrl() ) GetTextCtrl()->Undo(); } void wxComboBox::Redo() { if (IsEditable()) - GetText()->Redo(); + if ( GetTextCtrl() ) GetTextCtrl()->Redo(); } void wxComboBox::SelectAll() { - GetText()->SelectAll(); + if ( GetTextCtrl() ) GetTextCtrl()->SelectAll(); } bool wxComboBox::CanCopy() const { - if (GetText() != NULL) - return GetText()->CanCopy(); + if (GetTextCtrl() != NULL) + return GetTextCtrl()->CanCopy(); else return false; } bool wxComboBox::CanCut() const { - if (GetText() != NULL) - return GetText()->CanCut(); + if (GetTextCtrl() != NULL) + return GetTextCtrl()->CanCut(); else return false; } @@ -933,7 +496,7 @@ bool wxComboBox::CanCut() const bool wxComboBox::CanPaste() const { if (IsEditable()) - return GetText()->CanPaste(); + return GetTextCtrl()->CanPaste(); else return false; } @@ -941,7 +504,7 @@ bool wxComboBox::CanPaste() const bool wxComboBox::CanUndo() const { if (IsEditable()) - return GetText()->CanUndo(); + return GetTextCtrl()->CanUndo(); else return false; } @@ -949,62 +512,12 @@ bool wxComboBox::CanUndo() const bool wxComboBox::CanRedo() const { if (IsEditable()) - return GetText()->CanRedo(); + return GetTextCtrl()->CanRedo(); else return false; } -// ---------------------------------------------------------------------------- -// input handling -// ---------------------------------------------------------------------------- - -void wxComboControl::OnKey(wxKeyEvent& event) -{ - if ( m_isPopupShown ) - { - // pass it to the popped up control - (void)m_popup->GetControl()->ProcessEvent(event); - } - else // no popup - { - event.Skip(); - } -} - -bool wxComboControl::PerformAction(const wxControlAction& action, - long numArg, - const wxString& strArg) -{ - bool processed = false; - if ( action == wxACTION_COMBOBOX_POPUP ) - { - if ( !m_isPopupShown ) - { - ShowPopup(); - - processed = true; - } - } - else if ( action == wxACTION_COMBOBOX_DISMISS ) - { - if ( m_isPopupShown ) - { - HidePopup(); - - processed = true; - } - } - - if ( !processed ) - { - // pass along - return wxControl::PerformAction(action, numArg, strArg); - } - - return true; -} - // ---------------------------------------------------------------------------- // wxStdComboBoxInputHandler // ---------------------------------------------------------------------------- @@ -1043,4 +556,12 @@ bool wxStdComboBoxInputHandler::HandleKey(wxInputConsumer *consumer, return wxStdInputHandler::HandleKey(consumer, event, pressed); } +/* static */ +wxInputHandler *wxComboBox::GetStdInputHandler(wxInputHandler *handlerDef) +{ + static wxStdComboBoxInputHandler s_handler(handlerDef); + + return &s_handler; +} + #endif // wxUSE_COMBOBOX