]> git.saurik.com Git - wxWidgets.git/commitdiff
Refactored & cleaned up wxChoice & wxComboBox code, fixed client data
authorMattia Barbon <mbarbon@cpan.org>
Sun, 8 Dec 2002 18:48:05 +0000 (18:48 +0000)
committerMattia Barbon <mbarbon@cpan.org>
Sun, 8 Dec 2002 18:48:05 +0000 (18:48 +0000)
handling, implemented wxControlWIthItems' methods correctly, fixed a
couple of other bugs.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@18115 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/motif/choice.h
include/wx/motif/combobox.h
include/wx/motif/control.h
src/motif/choice.cpp
src/motif/combobox.cpp
src/motif/control.cpp

index ea94e39e032814c5a5cb0d98222cf8c502b8b7aa..070f5191e930321ceb70b59384828f70bce3b736 100644 (file)
 
 WXDLLEXPORT_DATA(extern const char*) wxChoiceNameStr;
 
+#include "wx/clntdata.h"
+#include "wx/dynarray.h"
+
+WX_DEFINE_ARRAY(WXWidget, wxWidgetArray);
+
 // Choice item
 class WXDLLEXPORT wxChoice: public wxChoiceBase
 {
     DECLARE_DYNAMIC_CLASS(wxChoice)
-        
+
 public:
     wxChoice();
     ~wxChoice();
@@ -35,6 +40,7 @@ public:
         const wxValidator& validator = wxDefaultValidator,
         const wxString& name = wxChoiceNameStr)
     {
+        Init();
         Create(parent, id, pos, size, n, choices, style, validator, name);
     }
     
@@ -45,39 +51,29 @@ public:
         long style = 0,
         const wxValidator& validator = wxDefaultValidator,
         const wxString& name = wxChoiceNameStr);
-    
-    // Virtual functions required by wxControlWithItems.
-    // They are not all implemented yet :-(
+
+    // implementation of wxControlWithItems
     virtual int GetCount() const;
     virtual int DoAppend(const wxString& item);
-    virtual void DoInsertItems(const wxArrayString& items, int pos);
-    virtual void DoSetItems(const wxArrayString& items, void **clientData);
-    virtual void DoSetFirstItem(int n);
     virtual void DoSetItemClientData(int n, void* clientData);
     virtual void* DoGetItemClientData(int n) const;
     virtual void DoSetItemClientObject(int n, wxClientData* clientData);
     virtual wxClientData* DoGetItemClientObject(int n) const;
-    virtual void Select(int n);
-    virtual void SetString(int n, const wxString& s);
-    
-    // Original API
-    //    virtual void Append(const wxString& item);
+    virtual int GetSelection() const;
     virtual void Delete(int n);
+    virtual int FindString(const wxString& s) const;
     virtual void Clear();
-    virtual int GetSelection() const ;
+    virtual void SetString(int n, const wxString& s);
+    virtual wxString GetString(int n) const;
+
+    // implementation of wxChoiceBase
     virtual void SetSelection(int n);
-    virtual int FindString(const wxString& s) const;
-    virtual wxString GetString(int n) const ;
-    
-    virtual wxString GetStringSelection() const ;
-    virtual bool SetStringSelection(const wxString& sel);
-    
-    virtual int Number() const { return m_noStrings; }
-    virtual void Command(wxCommandEvent& event);
-    
     virtual void SetColumns(int n = 1 );
     virtual int GetColumns() const ;
     
+    // Original API    
+    virtual void Command(wxCommandEvent& event);
+    
     void SetFocus();
     
     // Implementation
@@ -86,15 +82,25 @@ public:
     virtual void ChangeForegroundColour();
     WXWidget GetTopWidget() const { return m_formWidget; }
     WXWidget GetMainWidget() const { return m_buttonWidget; }
-    
+
+    virtual wxSize DoGetBestSize() const;
+
+    // implementation, for wxChoiceCallback
+    const wxWidgetArray& GetWidgets() const { return m_widgetArray; }
+    const wxStringList&  GetStrings() const { return m_stringList; }
 protected:
+    // minimum size for the text ctrl
+    wxSize GetItemsSize() const;
+    // common part of all contructors
+    void Init();
+
     int           m_noStrings;
     WXWidget      m_menuWidget;
     WXWidget      m_buttonWidget;
-    WXWidget*     m_widgetList ;
+    wxWidgetArray m_widgetArray;
     WXWidget      m_formWidget;
     wxStringList  m_stringList;
-    wxList        m_clientList;    // contains the client data for the items
+    wxClientDataDictionary m_clientDataDict;
      
     virtual void DoSetSize(int x, int y,
         int width, int height,
index 68980bf6b1755a961ef9f1d56b34404ae6c8ca1b..059c12c36a463a697d2fef40c8ccb86dd37cb0e1 100644 (file)
@@ -27,7 +27,7 @@ class WXDLLEXPORT wxComboBox: public wxChoice
     DECLARE_DYNAMIC_CLASS(wxComboBox)
         
 public:
-    inline wxComboBox() {}
+    wxComboBox() {}
     ~wxComboBox();
     
     inline wxComboBox(wxWindow *parent, wxWindowID id,
@@ -39,7 +39,8 @@ public:
         const wxValidator& validator = wxDefaultValidator,
         const wxString& name = wxComboBoxNameStr)
     {
-        Create(parent, id, value, pos, size, n, choices, style, validator, name);
+        Create(parent, id, value, pos, size, n, choices,
+               style, validator, name);
     }
     
     bool Create(wxWindow *parent, wxWindowID id,
@@ -51,17 +52,14 @@ public:
         const wxValidator& validator = wxDefaultValidator,
         const wxString& name = wxComboBoxNameStr);
     
-    // List functions
-    virtual void Append(const wxString& item);
+    // implementation of wxControlWithItems
+    virtual int DoAppend(const wxString& item);
     virtual void Delete(int n);
     virtual void Clear();
     virtual int GetSelection() const ;
     virtual void SetSelection(int n);
     virtual int FindString(const wxString& s) const;
     virtual wxString GetString(int n) const ;
-    virtual wxString GetStringSelection() const ;
-    virtual bool SetStringSelection(const wxString& sel);
-    virtual inline int Number() const { return m_noStrings; }
     
     // Text field functions
     virtual wxString GetValue() const ;
@@ -86,7 +84,8 @@ public:
     virtual void ChangeForegroundColour();
     WXWidget GetTopWidget() const { return m_mainWidget; }
     WXWidget GetMainWidget() const { return m_mainWidget; }
-    
+
+    virtual wxSize DoGetBestSize() const;
 protected:
     virtual void DoSetSize(int x, int y,
         int width, int height,
index b02955663264acf05d5d03818dbb949a6e9faf06..8dc7e270f09e31dfce469a2e4d3145a5368dacad 100644 (file)
@@ -65,6 +65,16 @@ public:
     bool InSetValue() const { return m_inSetValue; }
     
 protected:
+    // calls wxControlBase::CreateControl, also sets foreground, background and
+    // font to parent's values
+    bool CreateControl(wxWindow *parent,
+                       wxWindowID id,
+                       const wxPoint& pos,
+                       const wxSize& size,
+                       long style,
+                       const wxValidator& validator,
+                       const wxString& name);
+
 #if WXWIN_COMPATIBILITY
     wxFunction          m_callback;     // Callback associated with the window
 #endif // WXWIN_COMPATIBILITY
index e0afa97dd945b6e51accdcdb5859909aed48ae2d..79baba751acc1417e990d80b2200069714d48453 100644 (file)
@@ -43,10 +43,16 @@ void wxChoiceCallback (Widget w, XtPointer clientData,
 
 wxChoice::wxChoice()
 {
+    Init();
+}
+
+void wxChoice::Init()
+{
+    InitBase();
+
     m_noStrings = 0;
     m_buttonWidget = (WXWidget) 0;
     m_menuWidget = (WXWidget) 0;
-    m_widgetList = (WXWidget*) 0;
     m_formWidget = (WXWidget) 0;
 }
 
@@ -58,25 +64,8 @@ bool wxChoice::Create(wxWindow *parent, wxWindowID id,
                       const wxValidator& validator,
                       const wxString& name)
 {
-    SetName(name);
-    SetValidator(validator);
-    m_noStrings = 0; // Starts off with none, incremented in Append
-    m_windowStyle = style;
-    m_buttonWidget = (WXWidget) 0;
-    m_menuWidget = (WXWidget) 0;
-    m_widgetList = (WXWidget*) 0;
-    m_formWidget = (WXWidget) 0;
-
-    if (parent) parent->AddChild(this);
-
-    if ( id == -1 )
-        m_windowId = (int)NewControlId();
-    else
-        m_windowId = id;
-
-    m_backgroundColour = parent->GetBackgroundColour();
-    m_foregroundColour = parent->GetForegroundColour();
-    m_font = parent->GetFont();
+    if ( !CreateControl(parent, id, pos, size, style, validator, name) )
+        return FALSE;
 
     Widget parentWidget = (Widget) parent->GetClientWidget();
 
@@ -93,7 +82,8 @@ bool wxChoice::Create(wxWindow *parent, wxWindowID id,
     /*
     * Create the popup menu
     */
-    m_menuWidget = (WXWidget) XmCreatePulldownMenu ((Widget) m_formWidget, "choiceMenu", NULL, 0);
+    m_menuWidget = (WXWidget) XmCreatePulldownMenu ((Widget) m_formWidget,
+                                                    "choiceMenu", NULL, 0);
 
     //    int i;
     if (n > 0)
@@ -109,15 +99,13 @@ bool wxChoice::Create(wxWindow *parent, wxWindowID id,
     Arg args[10];
     Cardinal argcnt = 0;
 
-    XtSetArg (args[argcnt], XmNsubMenuId, (Widget) m_menuWidget);
-    argcnt++;
-    XtSetArg (args[argcnt], XmNmarginWidth, 0);
-    argcnt++;
-    XtSetArg (args[argcnt], XmNmarginHeight, 0);
-    argcnt++;
-    XtSetArg (args[argcnt], XmNpacking, XmPACK_TIGHT);
-    argcnt++;
-    m_buttonWidget = (WXWidget) XmCreateOptionMenu ((Widget) m_formWidget, "choiceButton", args, argcnt);
+    XtSetArg (args[argcnt], XmNsubMenuId, (Widget) m_menuWidget); ++argcnt;
+    XtSetArg (args[argcnt], XmNmarginWidth, 0); ++argcnt;
+    XtSetArg (args[argcnt], XmNmarginHeight, 0); ++argcnt;
+    XtSetArg (args[argcnt], XmNpacking, XmPACK_TIGHT); ++argcnt;
+    m_buttonWidget = (WXWidget) XmCreateOptionMenu ((Widget) m_formWidget,
+                                                    "choiceButton",
+                                                    args, argcnt);
 
     m_mainWidget = m_buttonWidget;
 
@@ -141,7 +129,8 @@ bool wxChoice::Create(wxWindow *parent, wxWindowID id,
 
     ChangeFont(FALSE);
 
-    AttachWidget (parent, m_buttonWidget, m_formWidget, pos.x, pos.y, size.x, size.y);
+    AttachWidget (parent, m_buttonWidget, m_formWidget,
+                  pos.x, pos.y, size.x, size.y);
 
     ChangeBackgroundColour();
 
@@ -155,8 +144,6 @@ wxChoice::~wxChoice()
     // be deleted implicitly by deleting the parent form
     // anyway.
     //  XtDestroyWidget (menuWidget);
-    if (m_widgetList)
-        delete[] m_widgetList;
 
     if (GetMainWidget())
     {
@@ -170,6 +157,8 @@ wxChoice::~wxChoice()
         m_mainWidget = (WXWidget) 0;
         m_buttonWidget = (WXWidget) 0;
     }
+    if ( HasClientObjectData() )
+        m_clientDataDict.DestroyData();
 }
 
 int wxChoice::DoAppend(const wxString& item)
@@ -189,23 +178,15 @@ int wxChoice::DoAppend(const wxString& item)
         XmNfontList, (XmFontList) m_font.GetFontList(1.0, XtDisplay((Widget) m_formWidget)),
         NULL);
 
-    WXWidget *new_widgetList = new WXWidget[m_noStrings + 1];
-    int i;
-    if (m_widgetList)
-        for (i = 0; i < m_noStrings; i++)
-            new_widgetList[i] = m_widgetList[i];
-
-    new_widgetList[m_noStrings] = (WXWidget) w;
-
-    if (m_widgetList)
-        delete[] m_widgetList;
-    m_widgetList = new_widgetList;
+    m_widgetArray.Add(w);
 
     char mnem = wxFindMnemonic ((char*) (const char*) item);
     if (mnem != 0)
         XtVaSetValues (w, XmNmnemonic, mnem, NULL);
 
-    XtAddCallback (w, XmNactivateCallback, (XtCallbackProc) wxChoiceCallback, (XtPointer) this);
+    XtAddCallback (w, XmNactivateCallback,
+                   (XtCallbackProc) wxChoiceCallback,
+                   (XtPointer) this);
 
     if (m_noStrings == 0 && m_buttonWidget)
     {
@@ -217,28 +198,22 @@ int wxChoice::DoAppend(const wxString& item)
             NULL);
         XmStringFree (text);
     }
-    wxNode *node = m_stringList.Add (item);
-    XtVaSetValues (w, XmNuserData, node->Data (), NULL);
-
-    if (m_noStrings == 0)
-        m_clientList.Append((wxObject*) NULL);
-    else
-        m_clientList.Insert( m_clientList.Item(m_noStrings-1),
-                                 (wxObject*) NULL );
+    m_stringList.Add(item);
     m_noStrings ++;
 
-    return Number() - 1;
+    return GetCount() - 1;
 }
 
-void wxChoice::Delete(int WXUNUSED(n))
+void wxChoice::Delete(int n)
 {
-    wxFAIL_MSG( "Sorry, wxChoice::Delete isn't implemented yet. Maybe you'd like to volunteer? :-)" );
+    Widget w = (Widget)m_widgetArray[n];
+    XtRemoveCallback(w, XmNactivateCallback, (XtCallbackProc)wxChoiceCallback,
+                     (XtPointer)this);
+    m_stringList.DeleteNode(m_stringList.Item(n));
+    m_widgetArray.RemoveAt(size_t(n));
+    m_clientDataDict.Delete(n, HasClientObjectData());
 
-    // What should we do -- remove the callback for this button widget,
-    // delete the m_stringList entry, delete the button widget, construct a new widget list
-    // (see Append)
-
-    // TODO
+    XtDestroyWidget(w);
     m_noStrings --;
 }
 
@@ -248,28 +223,20 @@ void wxChoice::Clear()
     int i;
     for (i = 0; i < m_noStrings; i++)
     {
-        XtUnmanageChild ((Widget) m_widgetList[i]);
-        XtDestroyWidget ((Widget) m_widgetList[i]);
+        XtRemoveCallback((Widget) m_widgetArray[i],
+                         XmNactivateCallback, (XtCallbackProc)wxChoiceCallback,
+                         (XtPointer)this);
+        XtUnmanageChild ((Widget) m_widgetArray[i]);
+        XtDestroyWidget ((Widget) m_widgetArray[i]);
     }
-    if (m_noStrings)
-        delete[] m_widgetList;
-    m_widgetList = (WXWidget*) NULL;
+    m_widgetArray.Clear();
     if (m_buttonWidget)
-        XtVaSetValues ((Widget) m_buttonWidget, XmNmenuHistory, (Widget) NULL, NULL);
+        XtVaSetValues ((Widget) m_buttonWidget,
+                       XmNmenuHistory, (Widget) NULL,
+                       NULL);
 
     if ( HasClientObjectData() )
-    {
-        // destroy the data (due to Robert's idea of using wxList<wxObject>
-        // and not wxList<wxClientData> we can't just say
-        // m_clientList.DeleteContents(TRUE) - this would crash!
-        wxNode *node = m_clientList.First();
-        while ( node )
-        {
-            delete (wxClientData *)node->Data();
-            node = node->Next();
-        }
-    }
-    m_clientList.Clear();
+        m_clientDataDict.DestroyData();
 
     m_noStrings = 0;
 }
@@ -286,10 +253,10 @@ int wxChoice::GetSelection() const
     if (XmStringGetLtoR (text, XmSTRING_DEFAULT_CHARSET, &s))
     {
         int i = 0;
-        for (wxNode * node = m_stringList.First (); node; node = node->Next ())
+        for (wxStringListNode* node = m_stringList.GetFirst ();
+             node; node = node->GetNext ())
         {
-            char *s1 = (char *) node->Data ();
-            if (s1 == s || strcmp (s1, s) == 0)
+            if (strcmp(node->GetData(), s) == 0)
             {
                 XmStringFree(text) ;
                 XtFree (s);
@@ -311,22 +278,30 @@ void wxChoice::SetSelection(int n)
 {
     m_inSetValue = TRUE;
 
-    wxNode *node = m_stringList.Nth (n);
+    wxStringListNode *node = m_stringList.Item(n);
     if (node)
     {
+#if 0
         Dimension selectionWidth, selectionHeight;
-
-        char *s = (char *) node->Data ();
-        XmString text = XmStringCreateSimple (s);
-        XtVaGetValues ((Widget) m_widgetList[n], XmNwidth, &selectionWidth, XmNheight, &selectionHeight, NULL);
+#endif
+        wxXmString text( (char*)node->Data() );
+// MBN: this seems silly, at best, and causes wxChoices to be clipped:
+//      will remove "soon"
+#if 0
+        XtVaGetValues ((Widget) m_widgetArray[n],
+                       XmNwidth, &selectionWidth,
+                       XmNheight, &selectionHeight,
+                       NULL);
+#endif
         Widget label = XmOptionButtonGadget ((Widget) m_buttonWidget);
         XtVaSetValues (label,
-            XmNlabelString, text,
+            XmNlabelString, text(),
             NULL);
-        XmStringFree (text);
+#if 0
         XtVaSetValues ((Widget) m_buttonWidget,
             XmNwidth, selectionWidth, XmNheight, selectionHeight,
-            XmNmenuHistory, (Widget) m_widgetList[n], NULL);
+            XmNmenuHistory, (Widget) m_widgetArray[n], NULL);
+#endif
     }
     m_inSetValue = FALSE;
 }
@@ -334,24 +309,23 @@ void wxChoice::SetSelection(int n)
 int wxChoice::FindString(const wxString& s) const
 {
     int i = 0;
-    for (wxNode * node = m_stringList.First (); node; node = node->Next ())
+    for (wxStringListNode* node = m_stringList.GetFirst();
+         node; node = node->GetNext ())
     {
-        char *s1 = (char *) node->Data ();
-        if (s == s1)
-        {
+        if (s == node->GetData())
             return i;
-        }
-        else
-            i++;
+
+        i++;
     }
+
     return -1;
 }
 
 wxString wxChoice::GetString(int n) const
 {
-    wxNode *node = m_stringList.Nth (n);
+    wxStringListNode *node = m_stringList.Item(n);
     if (node)
-        return wxString((char *) node->Data ());
+        return node->GetData();
     else
         return wxEmptyString;
 }
@@ -395,7 +369,9 @@ void wxChoice::DoSetSize(int x, int y, int width, int height, int sizeFlags)
     {
         int i;
         for (i = 0; i < m_noStrings; i++)
-            XtVaSetValues ((Widget) m_widgetList[i], XmNwidth, actualWidth, NULL);
+            XtVaSetValues ((Widget) m_widgetArray[i],
+                           XmNwidth, actualWidth,
+                           NULL);
         XtVaSetValues ((Widget) m_buttonWidget, XmNwidth, actualWidth,
             NULL);
     }
@@ -403,7 +379,9 @@ void wxChoice::DoSetSize(int x, int y, int width, int height, int sizeFlags)
     {
         int i;
         for (i = 0; i < m_noStrings; i++)
-            XtVaSetValues ((Widget) m_widgetList[i], XmNheight, actualHeight, NULL);
+            XtVaSetValues ((Widget) m_widgetArray[i],
+                           XmNheight, actualHeight,
+                           NULL);
         XtVaSetValues ((Widget) m_buttonWidget, XmNheight, actualHeight,
             NULL);
     }
@@ -415,27 +393,6 @@ void wxChoice::DoSetSize(int x, int y, int width, int height, int sizeFlags)
     wxControl::DoSetSize (x, y, width, height, sizeFlags);
 }
 
-wxString wxChoice::GetStringSelection () const
-{
-    int sel = GetSelection ();
-    if (sel > -1)
-        return wxString(this->GetString (sel));
-    else
-        return wxEmptyString;
-}
-
-bool wxChoice::SetStringSelection (const wxString& s)
-{
-    int sel = FindString (s);
-    if (sel > -1)
-    {
-        SetSelection (sel);
-        return TRUE;
-    }
-    else
-        return FALSE;
-}
-
 void wxChoice::Command(wxCommandEvent & event)
 {
     SetSelection (event.GetInt());
@@ -450,14 +407,17 @@ void wxChoiceCallback (Widget w, XtPointer clientData, XtPointer WXUNUSED(ptr))
         if (item->InSetValue())
             return;
 
-        char *s = NULL;
-        XtVaGetValues (w, XmNuserData, &s, NULL);
-        if (s)
+        int n = item->GetWidgets().Index(w);
+        if (n != wxNOT_FOUND)
         {
-            wxCommandEvent event (wxEVT_COMMAND_CHOICE_SELECTED, item->GetId());
+            wxCommandEvent event(wxEVT_COMMAND_CHOICE_SELECTED, item->GetId());
             event.SetEventObject(item);
-            event.m_commandInt = item->FindString (s);
-            //            event.m_commandString = s;
+            event.m_commandInt = n;
+            event.m_commandString = item->GetStrings().Item(n)->GetData();
+            if ( item->HasClientObjectData() )
+                event.SetClientObject( item->GetClientObject(n) );
+            else if ( item->HasClientUntypedData() )
+                event.SetClientData( item->GetClientData(n) );
             item->ProcessCommand (event);
         }
     }
@@ -474,14 +434,14 @@ void wxChoice::ChangeFont(bool keepOriginalSize)
         GetSize(& width, & height);
 
         XmFontList fontList = (XmFontList) m_font.GetFontList(1.0, XtDisplay((Widget) m_mainWidget));
-        XtVaSetValues ((Widget) m_mainWidget, XmNfontList, fontList, NULL);
+        XtVaSetValues ((Widget) m_formWidget, XmNfontList, fontList, NULL);
         XtVaSetValues ((Widget) m_buttonWidget, XmNfontList, fontList, NULL);
 
-        /* TODO: why does this cause a crash in XtWidgetToApplicationContext?
-        int i;
-        for (i = 0; i < m_noStrings; i++)
-        XtVaSetValues ((Widget) m_widgetList[i], XmNfontList, fontList, NULL);
-        */
+        for( size_t i = 0; i < m_noStrings; ++i )
+            XtVaSetValues( (Widget)m_widgetArray[i],
+                           XmNfontList, fontList,
+                           NULL );
+        
         GetSize(& width1, & height1);
         if (keepOriginalSize && (width != width1 || height != height1))
         {
@@ -497,7 +457,7 @@ void wxChoice::ChangeBackgroundColour()
     DoChangeBackgroundColour(m_menuWidget, m_backgroundColour);
     int i;
     for (i = 0; i < m_noStrings; i++)
-        DoChangeBackgroundColour(m_widgetList[i], m_backgroundColour);
+        DoChangeBackgroundColour(m_widgetArray[i], m_backgroundColour);
 }
 
 void wxChoice::ChangeForegroundColour()
@@ -507,95 +467,63 @@ void wxChoice::ChangeForegroundColour()
     DoChangeForegroundColour(m_menuWidget, m_foregroundColour);
     int i;
     for (i = 0; i < m_noStrings; i++)
-        DoChangeForegroundColour(m_widgetList[i], m_foregroundColour);
+        DoChangeForegroundColour(m_widgetArray[i], m_foregroundColour);
 }
 
-
-// These implement functions needed by wxControlWithItems.
-// Unfortunately, they're not all implemented yet.
-
 int wxChoice::GetCount() const
 {
-    return Number();
+    return m_noStrings;
 }
 
-/*
-int wxChoice::DoAppend(const wxString& item)
-{
-    Append(item);
-    return GetCount() - 1;
-}
-*/
-
-// Just appends, doesn't yet insert
-void wxChoice::DoInsertItems(const wxArrayString& items, int WXUNUSED(pos))
+void wxChoice::DoSetItemClientData(int n, void* clientData)
 {
-    size_t nItems = items.GetCount();
-
-    for ( size_t n = 0; n < nItems; n++ )
-    {
-        Append( items[n]);
-    }
+    m_clientDataDict.Set(n, (wxClientData*)clientData, FALSE);
 }
 
-void wxChoice::DoSetItems(const wxArrayString& items, void **WXUNUSED(clientData))
+void* wxChoice::DoGetItemClientData(int n) const
 {
-    Clear();
-    size_t nItems = items.GetCount();
-
-    for ( size_t n = 0; n < nItems; n++ )
-    {
-        Append(items[n]);
-    }
+    return (void*)m_clientDataDict.Get(n);
 }
 
-void wxChoice::DoSetFirstItem(int WXUNUSED(n))
+void wxChoice::DoSetItemClientObject(int n, wxClientData* clientData)
 {
-    wxFAIL_MSG( wxT("wxChoice::DoSetFirstItem not implemented") );
+    // don't delete, wxItemContainer does that for us
+    m_clientDataDict.Set(n, clientData, FALSE);
 }
 
-void wxChoice::DoSetItemClientData(int n, void* clientData)
+wxClientData* wxChoice::DoGetItemClientObject(int n) const
 {
-    wxNode *node = m_clientList.Nth( n );
-    wxCHECK_RET( node, wxT("invalid index in wxChoice::DoSetItemClientData") );
-
-    node->SetData( (wxObject*) clientData );
+    return m_clientDataDict.Get(n);
 }
 
-void* wxChoice::DoGetItemClientData(int n) const
+void wxChoice::SetString(int WXUNUSED(n), const wxString& WXUNUSED(s))
 {
-    wxNode *node = m_clientList.Nth( n );
-    wxCHECK_MSG( node, NULL, wxT("invalid index in wxChoice::DoGetItemClientData") );
-
-    return node->Data();
+    wxFAIL_MSG( wxT("wxChoice::SetString not implemented") );
 }
 
-void wxChoice::DoSetItemClientObject(int n, wxClientData* clientData)
+wxSize wxChoice::GetItemsSize() const
 {
-    wxNode *node = m_clientList.Nth( n );
-    wxCHECK_RET( node, wxT("invalid index in wxChoice::DoSetItemClientObject") );
+    int x, y, mx = 0, my = 0;
 
-    wxClientData *cd = (wxClientData*) node->Data();
-    delete cd;
+    // get my
+    GetTextExtent( "|", &x, &my );
 
-    node->SetData( (wxObject*) clientData );
-}
-
-wxClientData* wxChoice::DoGetItemClientObject(int n) const
-{
-    wxNode *node = m_clientList.Nth( n );
-    wxCHECK_MSG( node, (wxClientData *)NULL,
-                 wxT("invalid index in wxChoice::DoGetItemClientObject") );
-
-    return (wxClientData*) node->Data();
-}
+    wxStringList::Node* curr = m_stringList.GetFirst();
+    while( curr )
+    {
+        GetTextExtent( curr->GetData(), &x, &y );
+        mx = wxMax( mx, x );
+        my = wxMax( my, y );
+        curr = curr->GetNext();
+    }
 
-void wxChoice::Select(int n)
-{
-    SetSelection(n);
+    return wxSize( mx, my );
 }
 
-void wxChoice::SetString(int WXUNUSED(n), const wxString& WXUNUSED(s))
+wxSize wxChoice::DoGetBestSize() const
 {
-    wxFAIL_MSG( wxT("wxChoice::SetString not implemented") );
+    wxSize items = GetItemsSize();
+    // FIXME arbitrary constants
+    return wxSize( ( items.x ? items.x + 50 : 120 ),
+                     items.y + 15 );
 }
index e8e5fd66c70e84eccea6a6134cd55fcdcc48e530..72d2836507affec3d6037cfcfa1b906066af3a31 100644 (file)
@@ -26,6 +26,8 @@
 #endif
 #include "xmcombo/xmcombo.h"
 
+#include "wx/motif/private.h"
+
 void  wxComboBoxCallback (Widget w, XtPointer clientData,
                           XmComboBoxSelectionCallbackStruct * cbs);
 
@@ -40,20 +42,10 @@ bool wxComboBox::Create(wxWindow *parent, wxWindowID id,
                         const wxValidator& validator,
                         const wxString& name)
 {
-    SetName(name);
-    SetValidator(validator);
-    m_noStrings = n;
-    m_windowStyle = style;
-    m_backgroundColour = parent->GetBackgroundColour();
-    // m_backgroundColour = * wxWHITE;
-    m_foregroundColour = parent->GetForegroundColour();
-
-    if (parent) parent->AddChild(this);
+    if( !CreateControl( parent, id, pos, size, style, validator, name ) )
+        return FALSE;
 
-    if ( id == -1 )
-        m_windowId = (int)NewControlId();
-    else
-        m_windowId = id;
+    m_noStrings = n;
 
     Widget parentWidget = (Widget) parent->GetClientWidget();
 
@@ -70,12 +62,10 @@ bool wxComboBox::Create(wxWindow *parent, wxWindowID id,
     int i;
     for (i = 0; i < n; i++)
     {
-        XmString str = XmStringCreateLtoR((char*) (const char*) choices[i], XmSTRING_DEFAULT_CHARSET);
-        XmComboBoxAddItem(buttonWidget, str, 0);
-        XmStringFree(str);
+        wxXmString str( choices[i] );
+        XmComboBoxAddItem(buttonWidget, str(), 0);
         m_stringList.Add(choices[i]);
     }
-    m_noStrings = n;
 
     m_mainWidget = (Widget) buttonWidget;
 
@@ -83,7 +73,6 @@ bool wxComboBox::Create(wxWindow *parent, wxWindowID id,
 
     SetValue(value);
 
-    m_font = parent->GetFont();
     ChangeFont(FALSE);
 
     XtAddCallback (buttonWidget, XmNselectionCallback, (XtCallbackProc) wxComboBoxCallback,
@@ -104,12 +93,14 @@ wxComboBox::~wxComboBox()
     DetachWidget((Widget) m_mainWidget); // Removes event handlers
     XtDestroyWidget((Widget) m_mainWidget);
     m_mainWidget = (WXWidget) 0;
+    if ( HasClientObjectData() )
+        m_clientDataDict.DestroyData();
 }
 
 void wxComboBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
 {
     // Necessary so it doesn't call wxChoice::SetSize
-    wxWindow::DoSetSize(x, y, width, height, sizeFlags);
+    wxWindow::DoSetSize(x, y, width, DoGetBestSize().y, sizeFlags);
 }
 
 wxString wxComboBox::GetValue() const
@@ -128,39 +119,31 @@ wxString wxComboBox::GetValue() const
 void wxComboBox::SetValue(const wxString& value)
 {
     m_inSetValue = TRUE;
-    if (!value.IsNull())
-        XmComboBoxSetString ((Widget) m_mainWidget, (char*) (const char*) value);
+    if( !value.empty() )
+        XmComboBoxSetString( (Widget)m_mainWidget, (char*)value.c_str() );
     m_inSetValue = FALSE;
 }
 
-void wxComboBox::Append(const wxString& item)
+int wxComboBox::DoAppend(const wxString& item)
 {
-    XmString str = XmStringCreateLtoR((char*) (const char*) item, XmSTRING_DEFAULT_CHARSET);
-    XmComboBoxAddItem((Widget) m_mainWidget, str, 0);
+    wxXmString str( item.c_str() );
+    XmComboBoxAddItem((Widget) m_mainWidget, str(), 0);
     m_stringList.Add(item);
-    XmStringFree(str);
     m_noStrings ++;
+
+    return GetCount() - 1;
 }
 
 void wxComboBox::Delete(int n)
 {
-    XmComboBoxDeletePos((Widget) m_mainWidget, n-1);
+    XmComboBoxDeletePos((Widget) m_mainWidget, n+1);
     wxNode *node = m_stringList.Nth(n);
     if (node)
     {
         delete[] (char *)node->Data();
         delete node;
     }
-    node = m_clientList.Nth( n );
-    if (node)
-    {
-        if ( HasClientObjectData() )
-        {
-            delete (wxClientData *)node->Data();
-        }
-        delete node;
-    }
-
+    m_clientDataDict.Delete(n, HasClientObjectData());
     m_noStrings--;
 }
 
@@ -170,18 +153,7 @@ void wxComboBox::Clear()
     m_stringList.Clear();
 
     if ( HasClientObjectData() )
-    {
-        // destroy the data (due to Robert's idea of using wxList<wxObject>
-        // and not wxList<wxClientData> we can't just say
-        // m_clientList.DeleteContents(TRUE) - this would crash!
-        wxNode *node = m_clientList.First();
-        while ( node )
-        {
-            delete (wxClientData *)node->Data();
-            node = node->Next();
-        }
-    }
-    m_clientList.Clear();
+        m_clientDataDict.DestroyData();
     m_noStrings = 0;
 }
 
@@ -201,43 +173,20 @@ int wxComboBox::GetSelection (void) const
 
 wxString wxComboBox::GetString(int n) const
 {
-    wxNode *node = m_stringList.Nth (n);
+    wxNode *node = m_stringList.Nth(n);
     if (node)
         return wxString((char *) node->Data ());
     else
         return wxEmptyString;
 }
 
-wxString wxComboBox::GetStringSelection() const
-{
-    int sel = GetSelection();
-    if (sel == -1)
-        return wxEmptyString;
-    else
-        return GetString(sel);
-}
-
-bool wxComboBox::SetStringSelection(const wxString& sel)
-{
-    int n = FindString(sel);
-    if (n == -1)
-        return FALSE;
-    else
-    {
-        SetSelection(n);
-        return TRUE;
-    }
-}
-
 int wxComboBox::FindString(const wxString& s) const
 {
     int *pos_list = NULL;
     int count = 0;
-    XmString text = XmStringCreateSimple ((char*) (const char*) s);
+    wxXmString text( s );
     bool found = (XmComboBoxGetMatchPos((Widget) m_mainWidget,
-        text, &pos_list, &count) != 0);
-
-    XmStringFree(text);
+        text(), &pos_list, &count) != 0);
 
     if (found && count > 0)
     {
@@ -322,7 +271,11 @@ void  wxComboBoxCallback (Widget WXUNUSED(w), XtPointer clientData,
         {
             wxCommandEvent event (wxEVT_COMMAND_COMBOBOX_SELECTED, item->GetId());
             event.m_commandInt = cbs->index - 1;
-            //                event.m_commandString = item->GetString (event.m_commandInt);
+            event.m_commandString = item->GetString (event.m_commandInt);
+            if ( item->HasClientObjectData() )
+                event.SetClientObject( item->GetClientObject(cbs->index - 1) );
+            else if ( item->HasClientUntypedData() )
+                event.SetClientData( item->GetClientData(cbs->index - 1) );
             event.m_extraLong = TRUE;
             event.SetEventObject(item);
             item->ProcessCommand (event);
@@ -332,7 +285,7 @@ void  wxComboBoxCallback (Widget WXUNUSED(w), XtPointer clientData,
         {
             wxCommandEvent event (wxEVT_COMMAND_TEXT_UPDATED, item->GetId());
             event.m_commandInt = -1;
-            //                event.m_commandString = item->GetValue();
+            event.m_commandString = item->GetValue();
             event.m_extraLong = TRUE;
             event.SetEventObject(item);
             item->ProcessCommand (event);
@@ -356,7 +309,21 @@ void wxComboBox::ChangeBackgroundColour()
 
 void wxComboBox::ChangeForegroundColour()
 {
-    wxWindow::ChangeBackgroundColour();
+    wxWindow::ChangeForegroundColour();
+}
+
+wxSize wxComboBox::DoGetBestSize() const
+{
+    if( (GetWindowStyle() & wxCB_DROPDOWN) == wxCB_DROPDOWN ||
+        (GetWindowStyle() & wxCB_READONLY) == wxCB_READONLY )
+    {
+        wxSize items = GetItemsSize();
+        // FIXME arbitrary constants
+        return wxSize( ( items.x ? items.x + 50 : 120 ),
+                         items.y + 10 );
+    }
+    else
+        return wxWindow::DoGetBestSize();
 }
 
 #endif
index 1dc7e344c54a1c0ae1ceab45959b157b2a50708a..af57174fe6e3a7d404ee4107ce91ae7a564e8d71 100644 (file)
@@ -64,6 +64,25 @@ bool wxControl::Create( wxWindow *parent,
     return ret;
 }
 
+bool wxControl::CreateControl(wxWindow *parent,
+                              wxWindowID id,
+                              const wxPoint& pos,
+                              const wxSize& size,
+                              long style,
+                              const wxValidator& validator,
+                              const wxString& name)
+{
+    if( !wxControlBase::CreateControl( parent, id, pos, size, style,
+                                       validator, name ) )
+        return FALSE;
+
+    m_backgroundColour = parent->GetBackgroundColour();
+    m_foregroundColour = parent->GetForegroundColour();
+    m_font = parent->GetFont();
+
+    return TRUE;
+}
+
 void wxControl::SetLabel(const wxString& label)
 {
     Widget widget = (Widget) GetLabelWidget() ;