X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/bfc6fde4b1dd5bfd8ae22839ff9a69cf24eb9120..2adaf5969faf352d740f267b1a4ef79a2cf75980:/src/motif/choice.cpp diff --git a/src/motif/choice.cpp b/src/motif/choice.cpp index b950c67ef4..a25d112e25 100644 --- a/src/motif/choice.cpp +++ b/src/motif/choice.cpp @@ -13,20 +13,29 @@ #pragma implementation "choice.h" #endif +#ifdef __VMS +#define XtDisplay XTDISPLAY +#define XtParent XTPARENT +#endif + // For compilers that support precompilation, includes "wx.h". #include "wx/choice.h" #include "wx/utils.h" +#ifdef __VMS__ +#pragma message disable nosimpint +#endif #include #include #include #include +#ifdef __VMS__ +#pragma message enable nosimpint +#endif #include "wx/motif/private.h" -#if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxChoice, wxControl) -#endif void wxChoiceCallback (Widget w, XtPointer clientData, XtPointer ptr); @@ -56,35 +65,35 @@ bool wxChoice::Create(wxWindow *parent, wxWindowID id, 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_windowFont = parent->GetFont(); - + m_font = parent->GetFont(); + Widget parentWidget = (Widget) parent->GetClientWidget(); - - m_formWidget = (WXWidget) XtVaCreateManagedWidget ((char*) (const char*) name, + + m_formWidget = (WXWidget) XtVaCreateManagedWidget(name.c_str(), xmRowColumnWidgetClass, parentWidget, XmNmarginHeight, 0, XmNmarginWidth, 0, XmNpacking, XmPACK_TIGHT, XmNorientation, XmHORIZONTAL, NULL); - + XtVaSetValues ((Widget) m_formWidget, XmNspacing, 0, NULL); - + /* * Create the popup menu */ m_menuWidget = (WXWidget) XmCreatePulldownMenu ((Widget) m_formWidget, "choiceMenu", NULL, 0); - + // int i; if (n > 0) { @@ -92,13 +101,13 @@ bool wxChoice::Create(wxWindow *parent, wxWindowID id, for (i = 0; i < n; i++) Append (choices[i]); } - + /* * Create button */ Arg args[10]; Cardinal argcnt = 0; - + XtSetArg (args[argcnt], XmNsubMenuId, (Widget) m_menuWidget); argcnt++; XtSetArg (args[argcnt], XmNmarginWidth, 0); @@ -108,9 +117,9 @@ bool wxChoice::Create(wxWindow *parent, wxWindowID id, XtSetArg (args[argcnt], XmNpacking, XmPACK_TIGHT); argcnt++; m_buttonWidget = (WXWidget) XmCreateOptionMenu ((Widget) m_formWidget, "choiceButton", args, argcnt); - + m_mainWidget = m_buttonWidget; - + XtManageChild ((Widget) m_buttonWidget); // New code from Roland Haenel (roland_haenel@ac.cybercity.de) @@ -119,21 +128,22 @@ bool wxChoice::Create(wxWindow *parent, wxWindowID id, // that I have found the code responsible for this behaviour. #if XmVersion >= 1002 #if XmVersion < 2000 - Widget optionLabel = XmOptionLabelGadget ((Widget) m_buttonWidget); // JACS, 24/1/99: this seems to cause a malloc crash later on, e.g. // in controls sample. - // XtUnmanageChild (optionLabel); + // + // Widget optionLabel = XmOptionLabelGadget ((Widget) m_buttonWidget); + // XtUnmanageChild (optionLabel); #endif #endif XtVaSetValues((Widget) m_formWidget, XmNresizePolicy, XmRESIZE_NONE, NULL); - + ChangeFont(FALSE); AttachWidget (parent, m_buttonWidget, m_formWidget, pos.x, pos.y, size.x, size.y); - + ChangeBackgroundColour(); - + return TRUE; } @@ -146,15 +156,15 @@ wxChoice::~wxChoice() // XtDestroyWidget (menuWidget); if (m_widgetList) delete[] m_widgetList; - + if (GetMainWidget()) { DetachWidget(GetMainWidget()); // Removes event handlers DetachWidget(m_formWidget); - + XtDestroyWidget((Widget) m_formWidget); m_formWidget = (WXWidget) 0; - + // Presumably the other widgets have been deleted now, via the form m_mainWidget = (WXWidget) 0; m_buttonWidget = (WXWidget) 0; @@ -163,64 +173,68 @@ wxChoice::~wxChoice() void wxChoice::Append(const wxString& item) { - wxStripMenuCodes ((char *)(const char *)item, wxBuffer); - Widget w = XtVaCreateManagedWidget (wxBuffer, + Widget w = XtVaCreateManagedWidget (wxStripMenuCodes(item), #if USE_GADGETS xmPushButtonGadgetClass, (Widget) m_menuWidget, #else xmPushButtonWidgetClass, (Widget) m_menuWidget, #endif NULL); - + DoChangeBackgroundColour((WXWidget) w, m_backgroundColour); - - if (m_windowFont.Ok()) + + if (m_font.Ok()) XtVaSetValues (w, - XmNfontList, (XmFontList) m_windowFont.GetFontList(1.0, XtDisplay((Widget) m_formWidget)), + 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; - - char mnem = wxFindMnemonic ((char*) (const char*) item); - if (mnem != 0) - XtVaSetValues (w, XmNmnemonic, mnem, NULL); - - 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); - XmString text = XmStringCreateSimple ((char*) (const char*) item); - XtVaSetValues (label, - XmNlabelString, text, - NULL); - XmStringFree (text); - } - wxNode *node = m_stringList.Add (item); - XtVaSetValues (w, XmNuserData, node->Data (), NULL); - - m_noStrings ++; + + new_widgetList[m_noStrings] = (WXWidget) w; + + if (m_widgetList) + delete[] m_widgetList; + m_widgetList = new_widgetList; + + char mnem = wxFindMnemonic ((char*) (const char*) item); + if (mnem != 0) + XtVaSetValues (w, XmNmnemonic, mnem, NULL); + + 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); + XmString text = XmStringCreateSimple ((char*) (const char*) item); + XtVaSetValues (label, + XmNlabelString, text, + 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_noStrings ++; } void wxChoice::Delete(int WXUNUSED(n)) { wxFAIL_MSG( "Sorry, wxChoice::Delete isn't implemented yet. Maybe you'd like to volunteer? :-)" ); - + // 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 m_noStrings --; } @@ -239,6 +253,21 @@ void wxChoice::Clear() m_widgetList = (WXWidget*) NULL; if (m_buttonWidget) 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_noStrings = 0; } @@ -250,7 +279,7 @@ int wxChoice::GetSelection() const XtVaGetValues (label, XmNlabelString, &text, NULL); - + if (XmStringGetLtoR (text, XmSTRING_DEFAULT_CHARSET, &s)) { int i = 0; @@ -266,7 +295,7 @@ int wxChoice::GetSelection() const else i++; } // for() - + XmStringFree(text) ; XtFree (s); return -1; @@ -278,12 +307,12 @@ int wxChoice::GetSelection() const void wxChoice::SetSelection(int n) { m_inSetValue = TRUE; - + wxNode *node = m_stringList.Nth (n); if (node) { Dimension selectionWidth, selectionHeight; - + char *s = (char *) node->Data (); XmString text = XmStringCreateSimple (s); XtVaGetValues ((Widget) m_widgetList[n], XmNwidth, &selectionWidth, XmNheight, &selectionHeight, NULL); @@ -327,10 +356,10 @@ wxString wxChoice::GetString(int n) const void wxChoice::SetColumns(int n) { if (n<1) n = 1 ; - + short numColumns = n ; Arg args[3]; - + XtSetArg(args[0], XmNnumColumns, numColumns); XtSetArg(args[1], XmNpacking, XmPACK_COLUMN); XtSetValues((Widget) m_menuWidget,args,2) ; @@ -339,7 +368,7 @@ void wxChoice::SetColumns(int n) int wxChoice::GetColumns(void) const { short numColumns ; - + XtVaGetValues((Widget) m_menuWidget,XmNnumColumns,&numColumns,NULL) ; return numColumns ; } @@ -353,12 +382,12 @@ void wxChoice::DoSetSize(int x, int y, int width, int height, int sizeFlags) { XtVaSetValues((Widget) m_formWidget, XmNresizePolicy, XmRESIZE_ANY, NULL); bool managed = XtIsManaged((Widget) m_formWidget); - + if (managed) XtUnmanageChild ((Widget) m_formWidget); - + int actualWidth = width, actualHeight = height; - + if (width > -1) { int i; @@ -375,11 +404,11 @@ void wxChoice::DoSetSize(int x, int y, int width, int height, int sizeFlags) XtVaSetValues ((Widget) m_buttonWidget, XmNheight, actualHeight, NULL); } - + if (managed) XtManageChild ((Widget) m_formWidget); XtVaSetValues((Widget) m_formWidget, XmNresizePolicy, XmRESIZE_NONE, NULL); - + wxControl::DoSetSize (x, y, width, height, sizeFlags); } @@ -417,7 +446,7 @@ void wxChoiceCallback (Widget w, XtPointer clientData, XtPointer WXUNUSED(ptr)) { if (item->InSetValue()) return; - + char *s = NULL; XtVaGetValues (w, XmNuserData, &s, NULL); if (s) @@ -436,15 +465,15 @@ 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_windowFont.Ok()) + if (m_font.Ok()) { int width, height, width1, height1; GetSize(& width, & height); - - XmFontList fontList = (XmFontList) m_windowFont.GetFontList(1.0, XtDisplay((Widget) m_mainWidget)); + + XmFontList fontList = (XmFontList) m_font.GetFontList(1.0, XtDisplay((Widget) m_mainWidget)); XtVaSetValues ((Widget) m_mainWidget, 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++) @@ -477,3 +506,91 @@ void wxChoice::ChangeForegroundColour() for (i = 0; i < m_noStrings; i++) DoChangeForegroundColour(m_widgetList[i], m_foregroundColour); } + + +// These implement functions needed by wxControlWithItems. +// Unfortunately, they're not all implemented yet. + +int wxChoice::GetCount() const +{ + return Number(); +} + +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)) +{ + size_t nItems = items.GetCount(); + + for ( size_t n = 0; n < nItems; n++ ) + { + Append( items[n]); + } +} + +void wxChoice::DoSetItems(const wxArrayString& items, void **WXUNUSED(clientData)) +{ + Clear(); + size_t nItems = items.GetCount(); + + for ( size_t n = 0; n < nItems; n++ ) + { + Append(items[n]); + } +} + +void wxChoice::DoSetFirstItem(int WXUNUSED(n)) +{ + wxFAIL_MSG( wxT("wxChoice::DoSetFirstItem not implemented") ); +} + +void wxChoice::DoSetItemClientData(int n, void* clientData) +{ + wxNode *node = m_clientList.Nth( n ); + wxCHECK_RET( node, wxT("invalid index in wxChoice::DoSetItemClientData") ); + + node->SetData( (wxObject*) clientData ); +} + +void* wxChoice::DoGetItemClientData(int n) const +{ + wxNode *node = m_clientList.Nth( n ); + wxCHECK_MSG( node, NULL, wxT("invalid index in wxChoice::DoGetItemClientData") ); + + return node->Data(); +} + +void wxChoice::DoSetItemClientObject(int n, wxClientData* clientData) +{ + wxNode *node = m_clientList.Nth( n ); + wxCHECK_RET( node, wxT("invalid index in wxChoice::DoSetItemClientObject") ); + + wxClientData *cd = (wxClientData*) node->Data(); + delete cd; + + 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(); +} + +void wxChoice::Select(int n) +{ + SetSelection(n); +} + +void wxChoice::SetString(int WXUNUSED(n), const wxString& WXUNUSED(s)) +{ + wxFAIL_MSG( wxT("wxChoice::SetString not implemented") ); +}