From: Mattia Barbon Date: Sun, 8 Dec 2002 18:48:05 +0000 (+0000) Subject: Refactored & cleaned up wxChoice & wxComboBox code, fixed client data X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/ec75d791f043b3b43cac9825a2c62e9d5321e616 Refactored & cleaned up wxChoice & wxComboBox code, fixed client data 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 --- diff --git a/include/wx/motif/choice.h b/include/wx/motif/choice.h index ea94e39e03..070f5191e9 100644 --- a/include/wx/motif/choice.h +++ b/include/wx/motif/choice.h @@ -18,11 +18,16 @@ 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, diff --git a/include/wx/motif/combobox.h b/include/wx/motif/combobox.h index 68980bf6b1..059c12c36a 100644 --- a/include/wx/motif/combobox.h +++ b/include/wx/motif/combobox.h @@ -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, diff --git a/include/wx/motif/control.h b/include/wx/motif/control.h index b029556632..8dc7e270f0 100644 --- a/include/wx/motif/control.h +++ b/include/wx/motif/control.h @@ -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 diff --git a/src/motif/choice.cpp b/src/motif/choice.cpp index e0afa97dd9..79baba751a 100644 --- a/src/motif/choice.cpp +++ b/src/motif/choice.cpp @@ -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 - // and not wxList 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 ); } diff --git a/src/motif/combobox.cpp b/src/motif/combobox.cpp index e8e5fd66c7..72d2836507 100644 --- a/src/motif/combobox.cpp +++ b/src/motif/combobox.cpp @@ -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 - // and not wxList 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 diff --git a/src/motif/control.cpp b/src/motif/control.cpp index 1dc7e344c5..af57174fe6 100644 --- a/src/motif/control.cpp +++ b/src/motif/control.cpp @@ -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() ;