X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/fd304d989b2c5c35ac1a849d508cb21f4d54609e..64ea838d8f4d1853b7d850db93ee565e901d099a:/src/motif/choice.cpp diff --git a/src/motif/choice.cpp b/src/motif/choice.cpp index a3e57838b9..7557887c05 100644 --- a/src/motif/choice.cpp +++ b/src/motif/choice.cpp @@ -1,27 +1,25 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: choice.cpp +// Name: src/motif/choice.cpp // Purpose: wxChoice // Author: Julian Smart // Modified by: // Created: 17/09/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "choice.h" -#endif - -#ifdef __VMS -#define XtDisplay XTDISPLAY -#define XtParent XTPARENT -#endif +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" -#include "wx/defs.h" +#if wxUSE_CHOICE #include "wx/choice.h" -#include "wx/utils.h" + +#ifndef WX_PRECOMP + #include "wx/utils.h" + #include "wx/arrstr.h" +#endif #ifdef __VMS__ #pragma message disable nosimpint @@ -36,7 +34,9 @@ #include "wx/motif/private.h" -IMPLEMENT_DYNAMIC_CLASS(wxChoice, wxControl) +#define WIDTH_OVERHEAD 48 +#define WIDTH_OVERHEAD_SUBTRACT 40 +#define HEIGHT_OVERHEAD 15 void wxChoiceCallback (Widget w, XtPointer clientData, XtPointer ptr); @@ -48,9 +48,6 @@ wxChoice::wxChoice() void wxChoice::Init() { - InitBase(); - - m_noStrings = 0; m_buttonWidget = (WXWidget) 0; m_menuWidget = (WXWidget) 0; m_formWidget = (WXWidget) 0; @@ -65,7 +62,8 @@ bool wxChoice::Create(wxWindow *parent, wxWindowID id, const wxString& name) { if ( !CreateControl(parent, id, pos, size, style, validator, name) ) - return FALSE; + return false; + PreCreation(); Widget parentWidget = (Widget) parent->GetClientWidget(); @@ -75,6 +73,8 @@ bool wxChoice::Create(wxWindow *parent, wxWindowID id, XmNmarginWidth, 0, XmNpacking, XmPACK_TIGHT, XmNorientation, XmHORIZONTAL, + XmNresizeWidth, False, + XmNresizeHeight, False, NULL); XtVaSetValues ((Widget) m_formWidget, XmNspacing, 0, NULL); @@ -83,7 +83,8 @@ bool wxChoice::Create(wxWindow *parent, wxWindowID id, * Create the popup menu */ m_menuWidget = (WXWidget) XmCreatePulldownMenu ((Widget) m_formWidget, - "choiceMenu", NULL, 0); + wxMOTIF_STR("choiceMenu"), + NULL, 0); if (n > 0) { @@ -103,7 +104,7 @@ bool wxChoice::Create(wxWindow *parent, wxWindowID id, XtSetArg (args[argcnt], XmNmarginHeight, 0); ++argcnt; XtSetArg (args[argcnt], XmNpacking, XmPACK_TIGHT); ++argcnt; m_buttonWidget = (WXWidget) XmCreateOptionMenu ((Widget) m_formWidget, - "choiceButton", + wxMOTIF_STR("choiceButton"), args, argcnt); m_mainWidget = m_buttonWidget; @@ -130,14 +131,24 @@ bool wxChoice::Create(wxWindow *parent, wxWindowID id, XtVaSetValues((Widget) m_formWidget, XmNresizePolicy, XmRESIZE_NONE, NULL); - ChangeFont(FALSE); - + PostCreation(); AttachWidget (parent, m_buttonWidget, m_formWidget, pos.x, pos.y, bestSize.x, bestSize.y); - ChangeBackgroundColour(); + return true; +} - return TRUE; +bool wxChoice::Create(wxWindow *parent, wxWindowID id, + const wxPoint& pos, + const wxSize& size, + const wxArrayString& choices, + long style, + const wxValidator& validator, + const wxString& name) +{ + wxCArrayString chs(choices); + return Create(parent, id, pos, size, chs.GetCount(), chs.GetStrings(), + style, validator, name); } wxChoice::~wxChoice() @@ -160,70 +171,90 @@ wxChoice::~wxChoice() m_mainWidget = (WXWidget) 0; m_buttonWidget = (WXWidget) 0; } - if ( HasClientObjectData() ) - m_clientDataDict.DestroyData(); } -int wxChoice::DoAppend(const wxString& item) +static inline wxChar* MYcopystring(const wxChar* s) +{ + wxChar* copy = new wxChar[wxStrlen(s) + 1]; + return wxStrcpy(copy, s); +} + +// TODO auto-sorting is not supported by the code +int wxChoice::DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type) { - Widget w = XtVaCreateManagedWidget (wxStripMenuCodes(item), -#if USE_GADGETS - xmPushButtonGadgetClass, (Widget) m_menuWidget, +#ifndef XmNpositionIndex + wxCHECK_MSG( pos == GetCount(), -1, wxT("insert not implemented")); +#endif + + const unsigned int numItems = items.GetCount(); + AllocClientData(numItems); + for( unsigned int i = 0; i < numItems; ++i, ++pos ) + { + Widget w = XtVaCreateManagedWidget (GetLabelText(items[i]), +#if wxUSE_GADGETS + xmPushButtonGadgetClass, (Widget) m_menuWidget, #else - xmPushButtonWidgetClass, (Widget) m_menuWidget, + xmPushButtonWidgetClass, (Widget) m_menuWidget, #endif - NULL); +#ifdef XmNpositionIndex + XmNpositionIndex, pos, +#endif + NULL); - DoChangeBackgroundColour((WXWidget) w, m_backgroundColour); + wxDoChangeBackgroundColour((WXWidget) w, m_backgroundColour); - if (m_font.Ok()) - XtVaSetValues (w, - XmNfontList, (XmFontList) m_font.GetFontList(1.0, XtDisplay((Widget) m_formWidget)), - NULL); + if( m_font.IsOk() ) + wxDoChangeFont( w, m_font ); - m_widgetArray.Add(w); + m_widgetArray.Insert(w, pos); - char mnem = wxFindMnemonic ((char*) (const char*) item); - if (mnem != 0) - XtVaSetValues (w, XmNmnemonic, mnem, NULL); + char mnem = wxFindMnemonic (items[i]); + 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) - { - XtVaSetValues ((Widget) m_buttonWidget, XmNmenuHistory, w, NULL); - Widget label = XmOptionButtonGadget ((Widget) m_buttonWidget); - wxXmString text( item ); - XtVaSetValues (label, - XmNlabelString, text(), - NULL); + if (m_stringArray.GetCount() == 0 && m_buttonWidget) + { + XtVaSetValues ((Widget) m_buttonWidget, XmNmenuHistory, w, NULL); + Widget label = XmOptionButtonGadget ((Widget) m_buttonWidget); + wxXmString text( items[i] ); + XtVaSetValues (label, + XmNlabelString, text(), + NULL); + } + + m_stringArray.Insert(items[i], pos); + + InsertNewItemClientData(pos, clientData, i, type); } - m_stringList.Add(item); - m_noStrings ++; - return GetCount() - 1; + return pos - 1; } -void wxChoice::Delete(int n) +void wxChoice::DoDeleteOneItem(unsigned int n) { Widget w = (Widget)m_widgetArray[n]; XtRemoveCallback(w, XmNactivateCallback, (XtCallbackProc)wxChoiceCallback, (XtPointer)this); - m_stringList.DeleteNode(m_stringList.Item(n)); + + m_stringArray.RemoveAt(size_t(n)); m_widgetArray.RemoveAt(size_t(n)); - m_clientDataDict.Delete(n, HasClientObjectData()); + wxChoiceBase::DoDeleteOneItem(n); XtDestroyWidget(w); - m_noStrings --; } -void wxChoice::Clear() +void wxChoice::DoClear() { - m_stringList.Clear (); - size_t i; - for (i = 0; i < m_noStrings; i++) + m_stringArray.Clear(); + + unsigned int i; + for (i = 0; i < m_stringArray.GetCount(); i++) { XtRemoveCallback((Widget) m_widgetArray[i], XmNactivateCallback, (XtCallbackProc)wxChoiceCallback, @@ -231,112 +262,77 @@ void wxChoice::Clear() XtUnmanageChild ((Widget) m_widgetArray[i]); XtDestroyWidget ((Widget) m_widgetArray[i]); } + m_widgetArray.Clear(); if (m_buttonWidget) XtVaSetValues ((Widget) m_buttonWidget, XmNmenuHistory, (Widget) NULL, NULL); - if ( HasClientObjectData() ) - m_clientDataDict.DestroyData(); - - m_noStrings = 0; + wxChoiceBase::DoClear(); } int wxChoice::GetSelection() const { XmString text; - char *s; Widget label = XmOptionButtonGadget ((Widget) m_buttonWidget); XtVaGetValues (label, XmNlabelString, &text, NULL); + wxXmString freeMe(text); + wxString s = wxXmStringToString( text ); - if (XmStringGetLtoR (text, XmSTRING_DEFAULT_CHARSET, &s)) + if (!s.empty()) { - int i = 0; - for (wxStringListNode* node = m_stringList.GetFirst (); - node; node = node->GetNext ()) - { - if (strcmp(node->GetData(), s) == 0) - { - XmStringFree(text) ; - XtFree (s); + for (size_t i=0; iGetData() ); + wxXmString text( m_stringArray[n] ); // 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); + XtVaGetValues ((Widget) m_widgetArray[n], + XmNwidth, &selectionWidth, + XmNheight, &selectionHeight, + NULL); #endif - Widget label = XmOptionButtonGadget ((Widget) m_buttonWidget); - XtVaSetValues (label, - XmNlabelString, text(), - NULL); + Widget label = XmOptionButtonGadget ((Widget) m_buttonWidget); + XtVaSetValues (label, + XmNlabelString, text(), + NULL); #if 0 - XtVaSetValues ((Widget) m_buttonWidget, - XmNwidth, selectionWidth, XmNheight, selectionHeight, - XmNmenuHistory, (Widget) m_widgetArray[n], NULL); + XtVaSetValues ((Widget) m_buttonWidget, + XmNwidth, selectionWidth, XmNheight, selectionHeight, + XmNmenuHistory, (Widget) m_widgetArray[n], NULL); #endif - } - m_inSetValue = FALSE; -} -int wxChoice::FindString(const wxString& s) const -{ - int i = 0; - for (wxStringListNode* node = m_stringList.GetFirst(); - node; node = node->GetNext ()) - { - if (s == node->GetData()) - return i; - - i++; - } - - return -1; + m_inSetValue = false; } -wxString wxChoice::GetString(int n) const +wxString wxChoice::GetString(unsigned int n) const { - wxStringListNode *node = m_stringList.Item(n); - if (node) - return node->GetData(); - else - return wxEmptyString; + return m_stringArray[n]; } void wxChoice::SetColumns(int n) { if (n<1) n = 1 ; - short numColumns = n ; + short numColumns = (short)n ; Arg args[3]; XtSetArg(args[0], XmNnumColumns, numColumns); @@ -365,12 +361,13 @@ void wxChoice::DoSetSize(int x, int y, int width, int height, int sizeFlags) if (managed) XtUnmanageChild ((Widget) m_formWidget); - int actualWidth = width, actualHeight = height; + int actualWidth = width - WIDTH_OVERHEAD_SUBTRACT, + actualHeight = height - HEIGHT_OVERHEAD; if (width > -1) { - size_t i; - for (i = 0; i < m_noStrings; i++) + unsigned int i; + for (i = 0; i < m_stringArray.GetCount(); i++) XtVaSetValues ((Widget) m_widgetArray[i], XmNwidth, actualWidth, NULL); @@ -379,11 +376,13 @@ void wxChoice::DoSetSize(int x, int y, int width, int height, int sizeFlags) } if (height > -1) { - size_t i; - for (i = 0; i < m_noStrings; i++) +#if 0 + unsigned int i; + for (i = 0; i < m_stringArray.GetCount(); i++) XtVaSetValues ((Widget) m_widgetArray[i], XmNheight, actualHeight, NULL); +#endif XtVaSetValues ((Widget) m_buttonWidget, XmNheight, actualHeight, NULL); } @@ -414,8 +413,8 @@ void wxChoiceCallback (Widget w, XtPointer clientData, XtPointer WXUNUSED(ptr)) { wxCommandEvent event(wxEVT_COMMAND_CHOICE_SELECTED, item->GetId()); event.SetEventObject(item); - event.m_commandInt = n; - event.m_commandString = item->GetStrings().Item(n)->GetData(); + event.SetInt(n); + event.SetString( item->GetStrings().Item(n) ); if ( item->HasClientObjectData() ) event.SetClientObject( item->GetClientObject(n) ); else if ( item->HasClientUntypedData() ) @@ -430,75 +429,60 @@ void wxChoice::ChangeFont(bool keepOriginalSize) // Note that this causes the widget to be resized back // to its original size! We therefore have to set the size // back again. TODO: a better way in Motif? - if (m_font.Ok()) + if (m_mainWidget && m_font.IsOk()) { + Display* dpy = XtDisplay((Widget) m_mainWidget); int width, height, width1, height1; GetSize(& width, & height); - XmFontList fontList = (XmFontList) m_font.GetFontList(1.0, XtDisplay((Widget) m_mainWidget)); - XtVaSetValues ((Widget) m_formWidget, XmNfontList, fontList, NULL); - XtVaSetValues ((Widget) m_buttonWidget, XmNfontList, fontList, NULL); + WXString fontTag = wxFont::GetFontTag(); - for( size_t i = 0; i < m_noStrings; ++i ) + XtVaSetValues ((Widget) m_formWidget, + fontTag, m_font.GetFontTypeC(dpy), + NULL); + XtVaSetValues ((Widget) m_buttonWidget, + fontTag, m_font.GetFontTypeC(dpy), + NULL); + + for( unsigned int i = 0; i < m_stringArray.GetCount(); ++i ) XtVaSetValues( (Widget)m_widgetArray[i], - XmNfontList, fontList, + fontTag, m_font.GetFontTypeC(dpy), NULL ); - + GetSize(& width1, & height1); if (keepOriginalSize && (width != width1 || height != height1)) { - SetSize(-1, -1, width, height); + SetSize(wxDefaultCoord, wxDefaultCoord, width, height); } } } void wxChoice::ChangeBackgroundColour() { - DoChangeBackgroundColour(m_formWidget, m_backgroundColour); - DoChangeBackgroundColour(m_buttonWidget, m_backgroundColour); - DoChangeBackgroundColour(m_menuWidget, m_backgroundColour); - size_t i; - for (i = 0; i < m_noStrings; i++) - DoChangeBackgroundColour(m_widgetArray[i], m_backgroundColour); + wxDoChangeBackgroundColour(m_formWidget, m_backgroundColour); + wxDoChangeBackgroundColour(m_buttonWidget, m_backgroundColour); + wxDoChangeBackgroundColour(m_menuWidget, m_backgroundColour); + unsigned int i; + for (i = 0; i < m_stringArray.GetCount(); i++) + wxDoChangeBackgroundColour(m_widgetArray[i], m_backgroundColour); } void wxChoice::ChangeForegroundColour() { - DoChangeForegroundColour(m_formWidget, m_foregroundColour); - DoChangeForegroundColour(m_buttonWidget, m_foregroundColour); - DoChangeForegroundColour(m_menuWidget, m_foregroundColour); - size_t i; - for (i = 0; i < m_noStrings; i++) - DoChangeForegroundColour(m_widgetArray[i], m_foregroundColour); + wxDoChangeForegroundColour(m_formWidget, m_foregroundColour); + wxDoChangeForegroundColour(m_buttonWidget, m_foregroundColour); + wxDoChangeForegroundColour(m_menuWidget, m_foregroundColour); + unsigned int i; + for (i = 0; i < m_stringArray.GetCount(); i++) + wxDoChangeForegroundColour(m_widgetArray[i], m_foregroundColour); } -int wxChoice::GetCount() const +unsigned int wxChoice::GetCount() const { - return m_noStrings; + return m_stringArray.GetCount(); } -void wxChoice::DoSetItemClientData(int n, void* clientData) -{ - m_clientDataDict.Set(n, (wxClientData*)clientData, FALSE); -} - -void* wxChoice::DoGetItemClientData(int n) const -{ - return (void*)m_clientDataDict.Get(n); -} - -void wxChoice::DoSetItemClientObject(int n, wxClientData* clientData) -{ - // don't delete, wxItemContainer does that for us - m_clientDataDict.Set(n, clientData, FALSE); -} - -wxClientData* wxChoice::DoGetItemClientObject(int n) const -{ - return m_clientDataDict.Get(n); -} - -void wxChoice::SetString(int WXUNUSED(n), const wxString& WXUNUSED(s)) +void wxChoice::SetString(unsigned int WXUNUSED(n), const wxString& WXUNUSED(s)) { wxFAIL_MSG( wxT("wxChoice::SetString not implemented") ); } @@ -510,13 +494,11 @@ wxSize wxChoice::GetItemsSize() const // get my GetTextExtent( "|", &x, &my ); - wxStringList::Node* curr = m_stringList.GetFirst(); - while( curr ) + for (size_t i=0; iGetData(), &x, &y ); + GetTextExtent( m_stringArray[i], &x, &y ); mx = wxMax( mx, x ); my = wxMax( my, y ); - curr = curr->GetNext(); } return wxSize( mx, my ); @@ -526,6 +508,8 @@ wxSize wxChoice::DoGetBestSize() const { wxSize items = GetItemsSize(); // FIXME arbitrary constants - return wxSize( ( items.x ? items.x + 50 : 120 ), - items.y + 15 ); + return wxSize( ( items.x ? items.x + WIDTH_OVERHEAD : 120 ), + items.y + HEIGHT_OVERHEAD ); } + +#endif // wxUSE_CHOICE