X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0e320a79f187558effb04d92020b470372bbe456..ee92941afca091bf72d17e96ac8388545700d1fc:/src/os2/choice.cpp diff --git a/src/os2/choice.cpp b/src/os2/choice.cpp index a584d5303f..770da88ccc 100644 --- a/src/os2/choice.cpp +++ b/src/os2/choice.cpp @@ -1,119 +1,415 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: choice.cpp +// Name: src/os2/choice.cpp // Purpose: wxChoice -// Author: AUTHOR +// Author: David Webster // Modified by: -// Created: ??/??/98 +// Created: 10/13/99 // RCS-ID: $Id$ -// Copyright: (c) AUTHOR -// Licence: wxWindows licence +// Copyright: (c) David Webster +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "choice.h" -#endif - // For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#if wxUSE_CHOICE + #include "wx/choice.h" -#if !USE_SHARED_LIBRARY -IMPLEMENT_DYNAMIC_CLASS(wxChoice, wxControl) +#ifndef WX_PRECOMP + #include "wx/utils.h" + #include "wx/log.h" + #include "wx/settings.h" #endif -bool wxChoice::Create(wxWindow *parent, wxWindowID id, - const wxPoint& pos, - const wxSize& size, - int n, const wxString choices[], - long style, - const wxValidator& validator, - const wxString& name) -{ - SetName(name); - SetValidator(validator); - m_noStrings = n; - m_windowStyle = style; +#include "wx/os2/private.h" - if (parent) parent->AddChild(this); +IMPLEMENT_DYNAMIC_CLASS(wxChoice, wxControl) - if ( id == -1 ) - m_windowId = (int)NewControlId(); - else - m_windowId = id; +bool wxChoice::Create( + wxWindow* pParent +, wxWindowID vId +, const wxPoint& rPos +, const wxSize& rSize +, const wxArrayString& asChoices +, long lStyle +, const wxValidator& rValidator +, const wxString& rsName +) +{ + wxCArrayString chs(asChoices); - // TODO: create choice control - return FALSE; + return Create(pParent, vId, rPos, rSize, chs.GetCount(), chs.GetStrings(), + lStyle, rValidator, rsName); } -void wxChoice::Append(const wxString& item) +bool wxChoice::Create( + wxWindow* pParent +, wxWindowID vId +, const wxPoint& rPos +, const wxSize& rSize +, int n +, const wxString asChoices[] +, long lStyle +, const wxValidator& rValidator +, const wxString& rsName +) { - // TODO - m_noStrings ++; -} + long lSstyle; -void wxChoice::Delete(int n) + if (!CreateControl( pParent + ,vId + ,rPos + ,rSize + ,lStyle + ,rValidator + ,rsName + )) + return false; + lSstyle = CBS_DROPDOWNLIST | + WS_TABSTOP | + WS_VISIBLE; + + // clipping siblings does not yet work + // if (lStyle & wxCLIP_SIBLINGS ) + // lSstyle |= WS_CLIPSIBLINGS; + + wxASSERT_MSG( !(lStyle & wxCB_DROPDOWN) && + !(lStyle & wxCB_READONLY) && + !(lStyle & wxCB_SIMPLE), + wxT("this style flag is ignored by wxChoice, you " + "probably want to use a wxComboBox") ); + + if (!OS2CreateControl( wxT("COMBOBOX") + ,lSstyle + )) + return false; + + // + // A choice/combobox normally has a white background (or other, depending + // on global settings) rather than inheriting the parent's background colour. + // + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + + // initialize the controls contents + for (int i = 0; i < n; i++) + { + Append(asChoices[i]); + } + SetSize( rPos.x + ,rPos.y + ,rSize.x + ,rSize.y + ); + + // Set height to use with sizers i.e. without the dropdown listbox + wxFont vFont = GetFont(); + int nEditHeight; + wxGetCharSize( GetHWND(), NULL, &nEditHeight, &vFont ); + nEditHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nEditHeight); + SetBestFittingSize(wxSize(-1,nEditHeight+4)); // +2x2 for the border + + return true; +} // end of wxChoice::Create + +wxChoice::~wxChoice() { - // TODO - m_noStrings --; + Free(); } +// ---------------------------------------------------------------------------- +// adding/deleting items to/from the list +// ---------------------------------------------------------------------------- + +int wxChoice::DoAppend( + const wxString& rsItem +) +{ + int nIndex; + LONG nIndexType = 0; + if (m_windowStyle & wxCB_SORT) + nIndexType = LIT_SORTASCENDING; + else + nIndexType = LIT_END; + nIndex = (int)::WinSendMsg( GetHwnd() + ,LM_INSERTITEM + ,(MPARAM)nIndexType + ,(MPARAM)rsItem.c_str() + ); + return nIndex; +} // end of wxChoice::DoAppend + +int wxChoice::DoInsert( const wxString& rsItem, unsigned int pos ) +{ + wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list")); + wxCHECK_MSG(IsValidInsert(pos), -1, wxT("invalid index")); + + if (pos == GetCount()) + return DoAppend(rsItem); + + int nIndex; + LONG nIndexType = 0; + + if (m_windowStyle & wxCB_SORT) + nIndexType = LIT_SORTASCENDING; + else + nIndexType = pos; + nIndex = (int)::WinSendMsg( GetHwnd() + ,LM_INSERTITEM + ,(MPARAM)nIndexType + ,(MPARAM)rsItem.c_str() + ); + return nIndex; +} // end of wxChoice::DoInsert + +void wxChoice::Delete(unsigned int n) +{ + wxCHECK_RET( IsValid(n), wxT("invalid item index in wxChoice::Delete") ); + + if ( HasClientObjectData() ) + { + delete GetClientObject(n); + } + + ::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)n, (MPARAM)0); +} // end of wxChoice::Delete + void wxChoice::Clear() { - // TODO - m_noStrings = 0; -} + Free(); + ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0); +} // end of wxChoice::Clear + +// ---------------------------------------------------------------------------- +// selection +// ---------------------------------------------------------------------------- int wxChoice::GetSelection() const { - // TODO - return 0; -} + return((int)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0))); +} // end of wxChoice::GetSelection -void wxChoice::SetSelection(int n) +void wxChoice::SetSelection( + int n +) { - // TODO -} + ::WinSendMsg( GetHwnd() + ,LM_SELECTITEM + ,(MPARAM)n + ,(MPARAM)TRUE + ); +} // end of wxChoice::SetSelection + +// ---------------------------------------------------------------------------- +// string list functions +// ---------------------------------------------------------------------------- -int wxChoice::FindString(const wxString& s) const +unsigned int wxChoice::GetCount() const { - // TODO - return 0; -} + return((unsigned int)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMCOUNT, (MPARAM)0, (MPARAM)0))); +} // end of wxChoice::GetCount -wxString wxChoice::GetString(int n) const +void wxChoice::SetString(unsigned int n, const wxString& rsStr) { - // TODO - return wxString(""); -} + LONG nIndexType = 0; + void* pData; -void wxChoice::SetSize(int x, int y, int width, int height, int sizeFlags) + if ( m_clientDataItemsType != wxClientData_None ) + { + pData = DoGetItemClientData(n); + } + else // no client data + { + pData = NULL; + } + + ::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)n, 0); + + if (m_windowStyle & wxCB_SORT) + nIndexType = LIT_SORTASCENDING; + else + nIndexType = LIT_END; + ::WinSendMsg( GetHwnd() + ,LM_INSERTITEM + ,(MPARAM)nIndexType + ,(MPARAM)rsStr.c_str() + ); + + if (pData) + { + DoSetItemClientData(n, pData); + } +} // end of wxChoice::SetString + +wxString wxChoice::GetString(unsigned int n) const { - // TODO -} + int nLen = 0; + wxString sStr = wxEmptyString; + wxChar* zBuf; + + nLen = (size_t)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)n, (MPARAM)0)); + if (nLen != LIT_ERROR && nLen > 0) + { + zBuf = new wxChar[++nLen]; + ::WinSendMsg( GetHwnd() + ,LM_QUERYITEMTEXT + ,MPFROM2SHORT((SHORT)n, (SHORT)nLen) + ,(MPARAM)zBuf + ); + sStr = zBuf; + delete [] zBuf; + } + return sStr; +} // end of wxChoice::GetString + +// ---------------------------------------------------------------------------- +// client data +// ---------------------------------------------------------------------------- -wxString wxChoice::GetStringSelection () const +void wxChoice::DoSetItemClientData(unsigned int n, void* pClientData) { - int sel = GetSelection (); - if (sel > -1) - return wxString(this->GetString (sel)); - else - return wxString(""); -} + ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, (MPARAM)n, MPFROMP(pClientData)); +} // end of wxChoice::DoSetItemClientData -bool wxChoice::SetStringSelection (const wxString& s) +void* wxChoice::DoGetItemClientData(unsigned int n) const { - int sel = FindString (s); - if (sel > -1) - { - SetSelection (sel); - return TRUE; - } - else - return FALSE; -} + MRESULT rc = ::WinSendMsg(GetHwnd(), LM_QUERYITEMHANDLE, (MPARAM)n, (MPARAM)0); + return((void*)rc); +} // end of wxChoice::DoGetItemClientData -void wxChoice::Command(wxCommandEvent & event) +void wxChoice::DoSetItemClientObject(unsigned int n, wxClientData* pClientData) { - SetSelection (event.GetInt()); - ProcessCommand (event); -} + DoSetItemClientData(n, pClientData); +} // end of wxChoice::DoSetItemClientObject + +wxClientData* wxChoice::DoGetItemClientObject(unsigned int n) const +{ + return (wxClientData *)DoGetItemClientData(n); +} // end of wxChoice::DoGetItemClientObject + +// ---------------------------------------------------------------------------- +// wxOS2 specific helpers +// ---------------------------------------------------------------------------- + +void wxChoice::DoSetSize(int nX, + int nY, + int nWidth, + int WXUNUSED(nHeight), + int nSizeFlags) +{ + // + // Ignore height parameter because height doesn't mean 'initially + // displayed' height, it refers to the drop-down menu as well. The + // wxWidgets interpretation is different; also, getting the size returns + // the _displayed_ size (NOT the drop down menu size) so + // setting-getting-setting size would not work. + // + wxControl::DoSetSize( nX + ,nY + ,nWidth + ,wxDefaultCoord + ,nSizeFlags + ); +} // end of wxChoice::DoSetSize + +wxSize wxChoice::DoGetBestSize() const +{ + // + // Find the widest string + // + int nLineWidth; + int nChoiceWidth = 0; + int nCx; + int nCy; + wxFont vFont = (wxFont)GetFont(); + + const unsigned int nItems = GetCount(); + + for (unsigned int i = 0; i < nItems; i++) + { + wxString sStr(GetString(i)); + GetTextExtent( sStr, &nLineWidth, NULL ); + if (nLineWidth > nChoiceWidth) + nChoiceWidth = nLineWidth; + } + + // + // Give it some reasonable default value if there are no strings in the + // list + // + if (nChoiceWidth == 0L) + nChoiceWidth = 100L; + + // + // The combobox should be larger than the widest string + // + wxGetCharSize( GetHWND(), &nCx, &nCy, &vFont ); + nChoiceWidth += 5 * nCx; + + // + // Choice drop-down list depends on number of items (limited to 10) + // + size_t nStrings = nItems == 0 ? 10 : wxMin(10, nItems) + 1; + int nChoiceHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * nStrings; + + return wxSize(nChoiceWidth, nChoiceHeight); +} // end of wxChoice::DoGetBestSize + +MRESULT wxChoice::OS2WindowProc( + WXUINT uMsg +, WXWPARAM wParam +, WXLPARAM lParam +) +{ + return wxWindow::OS2WindowProc( uMsg + ,wParam + ,lParam + ); +} // end of wxChoice::OS2WindowProc + +bool wxChoice::OS2Command( + WXUINT uParam +, WXWORD WXUNUSED(wId) +) +{ + if (uParam != LN_SELECT) + { + // + // "selection changed" is the only event we're after + // + return false; + } + int n = GetSelection(); + + if (n > -1) + { + wxCommandEvent vEvent( wxEVT_COMMAND_CHOICE_SELECTED + ,m_windowId + ); + + vEvent.SetInt(n); + vEvent.SetEventObject(this); + vEvent.SetString(GetStringSelection()); + if (HasClientObjectData()) + vEvent.SetClientObject(GetClientObject(n)); + else if (HasClientUntypedData()) + vEvent.SetClientData(GetClientData(n)); + ProcessCommand(vEvent); + } + return true; +} // end of wxChoice::OS2Command + +void wxChoice::Free() +{ + if (HasClientObjectData()) + { + const unsigned int nCount = GetCount(); + + for (unsigned int n = 0; n < nCount; n++) + { + delete GetClientObject(n); + } + } +} // end of wxChoice::Free +#endif // wxUSE_CHOICE