X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e9576ca53db96b462ed4c0b4bdf47d64c40203e4..757cc9def70e4685054f4a24238e2df111f6c9fd:/src/mac/combobox.cpp diff --git a/src/mac/combobox.cpp b/src/mac/combobox.cpp index 0be841bad4..e67e1d9601 100644 --- a/src/mac/combobox.cpp +++ b/src/mac/combobox.cpp @@ -6,7 +6,7 @@ // Created: ??/??/98 // RCS-ID: $Id$ // Copyright: (c) AUTHOR -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ @@ -14,67 +14,321 @@ #endif #include "wx/combobox.h" +#include "wx/menu.h" +#include "wx/mac/uma.h" #if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxComboBox, wxControl) #endif +// composite combobox implementation by Dan "Bud" Keith bud@otsys.com + + +static int nextPopUpMenuId = 1000 ; +MenuHandle NewUniqueMenu() +{ + MenuHandle handle = NewMenu( nextPopUpMenuId , "\pMenu" ) ; + nextPopUpMenuId++ ; + return handle ; +} + + +// ---------------------------------------------------------------------------- +// constants +// ---------------------------------------------------------------------------- + +// the margin between the text control and the choice +static const wxCoord MARGIN = 2; +static const int POPUPWIDTH = 18; +static const int POPUPHEIGHT = 23; + + +// ---------------------------------------------------------------------------- +// wxComboBoxText: text control forwards events to combobox +// ---------------------------------------------------------------------------- + +class wxComboBoxText : public wxTextCtrl +{ +public: + wxComboBoxText( wxComboBox * cb ) + : wxTextCtrl( cb->GetParent(), 1 ) + { + m_cb = cb; + } + +protected: + void OnTextChange( wxCommandEvent& event ) + { + wxString s = GetValue(); + + if (!s.IsEmpty()) + m_cb->DelegateTextChanged( s ); + + event.Skip(); + } + +private: + wxComboBox *m_cb; + + DECLARE_EVENT_TABLE() +}; + +BEGIN_EVENT_TABLE(wxComboBoxText, wxTextCtrl) + EVT_TEXT(-1, wxComboBoxText::OnTextChange) +END_EVENT_TABLE() + +class wxComboBoxChoice : public wxChoice +{ +public: + wxComboBoxChoice(wxComboBox *cb, int style) + : wxChoice( cb->GetParent(), 1 ) + { + m_cb = cb; + } + +protected: + void OnChoice( wxCommandEvent& e ) + { + wxString s = e.GetString(); + + m_cb->DelegateChoice( s ); + } + +private: + wxComboBox *m_cb; + + DECLARE_EVENT_TABLE() +}; + +BEGIN_EVENT_TABLE(wxComboBoxChoice, wxChoice) + EVT_CHOICE(-1, wxComboBoxChoice::OnChoice) +END_EVENT_TABLE() + +wxComboBox::~wxComboBox() +{ + // delete the controls now, don't leave them alive even though they would + // still be eventually deleted by our parent - but it will be too late, the + // user code expects them to be gone now + if (m_text != NULL) { + delete m_text; + m_text = NULL; + } + if (m_choice != NULL) { + delete m_choice; + m_choice = NULL; + } +} + + +// ---------------------------------------------------------------------------- +// geometry +// ---------------------------------------------------------------------------- + +wxSize wxComboBox::DoGetBestSize() const +{ + wxSize size = m_choice->GetBestSize(); + + if ( m_text != 0 ) + { + wxSize sizeText = m_text->GetBestSize(); + + size.x = POPUPWIDTH + sizeText.x + MARGIN; + } + + return size; +} + +void wxComboBox::DoMoveWindow(int x, int y, int width, int height) { + height = POPUPHEIGHT; + + wxControl::DoMoveWindow(x, y, width, height); + + if ( m_text == 0 ) + { + m_choice->SetSize(x, y, width, -1); + } + else + { + wxCoord wText = width - POPUPWIDTH; + m_text->SetSize(x, y, wText, height); + m_choice->SetSize(x + wText + MARGIN, y, POPUPWIDTH, -1); + } +} + + + +// ---------------------------------------------------------------------------- +// operations forwarded to the subcontrols +// ---------------------------------------------------------------------------- + +bool wxComboBox::Enable(bool enable) +{ + if ( !wxControl::Enable(enable) ) + return FALSE; + + m_choice->Enable(enable); + + if ( m_text != 0 ) + { + m_text->Enable(enable); + } + + return TRUE; +} + +bool wxComboBox::Show(bool show) +{ + if ( !wxControl::Show(show) ) + return FALSE; + + // under GTK Show() is called the first time before we are fully + // constructed + if ( m_choice ) + { + m_choice->Show(show); + if ( m_text != 0 ) + { + m_text->Show(show); + } + } + + return TRUE; +} + + void wxComboBox::SetFocus() + { + m_text->SetFocus(); + } + + +void wxComboBox::DelegateTextChanged( const wxString& value ) { +} + + +void wxComboBox::DelegateChoice( const wxString& value ) +{ + SetStringSelection( value ); +} + + bool wxComboBox::Create(wxWindow *parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, - int n, const wxString choices[], - long style, + int n, const wxString choices[], + long style, const wxValidator& validator, const wxString& name) { - SetName(name); - SetValidator(validator); - m_noStrings = n; - m_windowStyle = style; - if (parent) parent->AddChild(this); + Rect bounds ; + Str255 title ; + + if ( !wxControl::Create(parent, id, pos, size, style, + wxDefaultValidator, name) ) + { + return FALSE; + } + + m_choice = new wxComboBoxChoice(this, style); - if ( id == -1 ) - m_windowId = (int)NewControlId(); + wxSize csize = size; + if ( style & wxCB_READONLY ) + { + m_text = 0; + } else - m_windowId = id; + { + m_text = new wxComboBoxText(this); + if ( size.y == -1 ) { + csize.y = m_text->GetSize().y ; + } + } + + DoSetSize(pos.x, pos.y, csize.x, csize.y); + for ( int i = 0 ; i < n ; i++ ) + { + m_choice->DoAppend( choices[ i ] ); + } - // TODO: create combobox control + // 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; + + // we don't even need to show this window itself - and not doing it avoids + // that it overwrites the text control + wxControl::Show(FALSE); return TRUE; } wxString wxComboBox::GetValue() const { - // TODO - return wxString(""); + wxString result; + + if ( m_text == 0 ) + { + result = m_choice->GetString( m_choice->GetSelection() ); + } + else + { + result = m_text->GetValue(); + } + + return result; } void wxComboBox::SetValue(const wxString& value) { - // TODO + SetStringSelection( value ) ; } // Clipboard operations void wxComboBox::Copy() { - // TODO + if ( m_text != 0 ) + { + m_text->Copy(); + } } void wxComboBox::Cut() { - // TODO + if ( m_text != 0 ) + { + m_text->Cut(); + } } void wxComboBox::Paste() { - // TODO + if ( m_text != 0 ) + { + m_text->Paste(); + } } void wxComboBox::SetEditable(bool editable) { - // TODO + if ( ( m_text == 0 ) && editable ) + { + m_text = new wxComboBoxText( this ); + } + else if ( ( m_text != 0 ) && !editable ) + { + delete m_text; + m_text = 0; + } + + int currentX, currentY; + GetPosition( ¤tX, ¤tY ); + + int currentW, currentH; + GetSize( ¤tW, ¤tH ); + + DoMoveWindow( currentX, currentY, currentW, currentH ); } void wxComboBox::SetInsertionPoint(long pos) @@ -116,50 +370,75 @@ void wxComboBox::SetSelection(long from, long to) void wxComboBox::Append(const wxString& item) { - // TODO + // I am not sure what other ports do, + // but wxMac chokes on empty entries. + + if (!item.IsEmpty()) + m_choice->DoAppend( item ); } void wxComboBox::Delete(int n) { - // TODO + m_choice->Delete( n ); } void wxComboBox::Clear() { - // TODO + m_choice->Clear(); } int wxComboBox::GetSelection() const { - // TODO - return -1; + return m_choice->GetSelection(); } void wxComboBox::SetSelection(int n) { - // TODO + m_choice->SetSelection( n ); + + if ( m_text != 0 ) + { + m_text->SetValue( GetString( n ) ); + } } int wxComboBox::FindString(const wxString& s) const { - // TODO - return -1; + return m_choice->FindString( s ); } wxString wxComboBox::GetString(int n) const { - // TODO - return wxString(""); + return m_choice->GetString( n ); } wxString wxComboBox::GetStringSelection() const { - // TODO - return wxString(""); + int sel = GetSelection (); + if (sel > -1) + return wxString(this->GetString (sel)); + else + return wxString(""); } bool wxComboBox::SetStringSelection(const wxString& sel) { - // TODO - return FALSE; + int s = FindString (sel); + if (s > -1) + { + SetSelection (s); + return TRUE; + } + else + return FALSE; } + +void wxComboBox::MacHandleControlClick( WXWidget control , wxInt16 controlpart ) +{ + wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_SELECTED, m_windowId ); + event.SetInt(GetSelection()); + event.SetEventObject(this); + event.SetString(GetStringSelection()); + ProcessCommand(event); +} +