]> git.saurik.com Git - wxWidgets.git/blobdiff - src/os2/choice.cpp
Move MinGW builds to another machine as td165 is down.
[wxWidgets.git] / src / os2 / choice.cpp
index a584d5303fb41c40ef4ba78fe4aa66f5e8b13818..9f0360a9fcbb2a59d24436fd34d300effd6ff461 100644 (file)
 /////////////////////////////////////////////////////////////////////////////
-// 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, wxControlWithItems)
 
-    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;
+
+    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);
+    SetInitialSize(wxSize(-1,nEditHeight+4));   // +2x2 for the border
+
+    return true;
+} // end of wxChoice::Create
 
-void wxChoice::Delete(int n)
+wxChoice::~wxChoice()
 {
-    // TODO
-    m_noStrings --;
+    Clear();
 }
 
-void wxChoice::Clear()
+// ----------------------------------------------------------------------------
+// adding/deleting items to/from the list
+// ----------------------------------------------------------------------------
+
+int wxChoice::DoInsertItems(const wxArrayStringsAdapter& items
+                           , unsigned int pos
+                           , void **clientData
+                           , wxClientDataType type
+                           )
 {
-    // TODO
-    m_noStrings = 0;
-}
+    int                             nIndex = wxNOT_FOUND;
+    LONG                            nIndexType = 0;
+    bool                            incrementPos = false;
+    if ( IsSorted() )
+        nIndexType = LIT_SORTASCENDING;
+    else if (pos == GetCount())
+        nIndexType = LIT_END;
+    else
+    {
+        nIndexType = pos;
+        incrementPos = true;
+    }
 
-int wxChoice::GetSelection() const
+    const unsigned int count = items.GetCount();
+    for( unsigned int i = 0; i < count; ++i )
+    {
+        nIndex = (int)::WinSendMsg( GetHwnd()
+                                   ,LM_INSERTITEM
+                                   ,(MPARAM)nIndexType
+                                   ,(MPARAM)items[i].wx_str()
+                                  );
+        if (nIndex < 0)
+        {
+            nIndex = wxNOT_FOUND;
+            break;
+        }
+        AssignNewItemClientData(nIndex, clientData, i, type);
+
+        if (incrementPos)
+            ++nIndexType;
+    }
+    return nIndex;
+} // end of wxChoice::DoInsertAppendItemsWithData
+
+void wxChoice::DoDeleteOneItem(unsigned int n)
 {
-    // TODO
-    return 0;
-}
+    wxCHECK_RET( IsValid(n), wxT("invalid item index in wxChoice::Delete") );
+
+    ::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)n, (MPARAM)0);
+} // end of wxChoice::Delete
 
-void wxChoice::SetSelection(int n)
+void wxChoice::DoClear()
 {
-    // TODO
-}
+    ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
+} // end of wxChoice::Clear
+
+// ----------------------------------------------------------------------------
+// selection
+// ----------------------------------------------------------------------------
 
-int wxChoice::FindString(const wxString& s) const
+int wxChoice::GetSelection() const
 {
-    // TODO
-    return 0;
-}
+    return((int)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0)));
+} // end of wxChoice::GetSelection
 
-wxString wxChoice::GetString(int n) const
+void wxChoice::SetSelection(
+  int                               n
+)
 {
-    // TODO
-    return wxString("");
-}
+    ::WinSendMsg( GetHwnd()
+                 ,LM_SELECTITEM
+                 ,(MPARAM)n
+                 ,(MPARAM)TRUE
+                );
+} // end of wxChoice::SetSelection
+
+// ----------------------------------------------------------------------------
+// string list functions
+// ----------------------------------------------------------------------------
 
-void wxChoice::SetSize(int x, int y, int width, int height, int sizeFlags)
+unsigned int wxChoice::GetCount() const
 {
-    // TODO
-}
+    return((unsigned int)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMCOUNT, (MPARAM)0, (MPARAM)0)));
+} // end of wxChoice::GetCount
 
-wxString wxChoice::GetStringSelection () const
+void wxChoice::SetString(unsigned int n, const wxString& rsStr)
 {
-    int sel = GetSelection ();
-    if (sel > -1)
-        return wxString(this->GetString (sel));
+    LONG  nIndexType = 0;
+    void* pData;
+
+    if ( HasClientData() )
+    {
+        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
-        return wxString("");
-}
+        nIndexType = LIT_END;
+    ::WinSendMsg( GetHwnd()
+                 ,LM_INSERTITEM
+                 ,(MPARAM)nIndexType
+                 ,(MPARAM)rsStr.wx_str()
+                );
+
+    if (pData)
+    {
+        DoSetItemClientData(n, pData);
+    }
+} // end of wxChoice::SetString
 
-bool wxChoice::SetStringSelection (const wxString& s)
+wxString wxChoice::GetString(unsigned int n) const
 {
-    int sel = FindString (s);
-    if (sel > -1)
-        {
-            SetSelection (sel);
-            return TRUE;
-        }
-    else
-        return FALSE;
-}
+    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
+// ----------------------------------------------------------------------------
 
-void wxChoice::Command(wxCommandEvent & event)
+void wxChoice::DoSetItemClientData(unsigned int n, void* pClientData)
 {
-    SetSelection (event.GetInt());
-    ProcessCommand (event);
-}
+    ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, (MPARAM)n, MPFROMP(pClientData));
+} // end of wxChoice::DoSetItemClientData
+
+void* wxChoice::DoGetItemClientData(unsigned int n) const
+{
+    MRESULT rc = ::WinSendMsg(GetHwnd(), LM_QUERYITEMHANDLE, (MPARAM)n, (MPARAM)0);
+    return((void*)rc);
+} // end of wxChoice::DoGetItemClientData
+
+// ----------------------------------------------------------------------------
+// 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
 
+#endif // wxUSE_CHOICE