1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/motif/combobox.cpp 
   3 // Purpose:     wxComboBox class 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  17 #include "wx/combobox.h" 
  20     #include "wx/arrstr.h" 
  24 #pragma message disable nosimpint 
  28 #pragma message enable nosimpint 
  31 // use the old, GPL'd combobox 
  32 #if (XmVersion < 2000) 
  34 #include "xmcombo/xmcombo.h" 
  36 #include "wx/motif/private.h" 
  38 void  wxComboBoxCallback (Widget w
, XtPointer clientData
, 
  39                           XmComboBoxSelectionCallbackStruct 
* cbs
); 
  41 IMPLEMENT_DYNAMIC_CLASS(wxComboBox
, wxControl
) 
  43 bool wxComboBox::Create(wxWindow 
*parent
, wxWindowID id
, 
  44                         const wxString
& value
, 
  47                         int n
, const wxString choices
[], 
  49                         const wxValidator
& validator
, 
  52     if( !CreateControl( parent
, id
, pos
, size
, style
, validator
, name 
) ) 
  58     Widget parentWidget 
= (Widget
) parent
->GetClientWidget(); 
  60     Widget buttonWidget 
= XtVaCreateManagedWidget(name
.c_str(), 
  61         xmComboBoxWidgetClass
, parentWidget
, 
  65         XmNeditable
, ((style 
& wxCB_READONLY
) != wxCB_READONLY
), 
  66         XmNsorted
, ((style 
& wxCB_SORT
) == wxCB_SORT
), 
  67         XmNstaticList
, ((style 
& wxCB_SIMPLE
) == wxCB_SIMPLE
), 
  71     for (i 
= 0; i 
< n
; i
++) 
  73         wxXmString 
str( choices
[i
] ); 
  74         XmComboBoxAddItem(buttonWidget
, str(), 0); 
  75         m_stringList
.Add(choices
[i
]); 
  78     m_mainWidget 
= (Widget
) buttonWidget
; 
  80     XtManageChild (buttonWidget
); 
  84     XtAddCallback (buttonWidget
, XmNselectionCallback
, (XtCallbackProc
) wxComboBoxCallback
, 
  86     XtAddCallback (buttonWidget
, XmNvalueChangedCallback
, (XtCallbackProc
) wxComboBoxCallback
, 
  90     AttachWidget (parent
, m_mainWidget
, (WXWidget
) NULL
, pos
.x
, pos
.y
, size
.x
, size
.y
); 
  95 bool wxComboBox::Create(wxWindow 
*parent
, wxWindowID id
, 
  96                         const wxString
& value
, 
  99                         const wxArrayString
& choices
, 
 101                         const wxValidator
& validator
, 
 102                         const wxString
& name
) 
 104     wxCArrayString 
chs(choices
); 
 105     return Create(parent
, id
, value
, pos
, size
, chs
.GetCount(), 
 106                   chs
.GetStrings(), style
, validator
, name
); 
 109 wxComboBox::~wxComboBox() 
 111     DetachWidget((Widget
) m_mainWidget
); // Removes event handlers 
 112     XtDestroyWidget((Widget
) m_mainWidget
); 
 113     m_mainWidget 
= (WXWidget
) 0; 
 116 void wxComboBox::DoSetSize(int x
, int y
, 
 117                            int width
, int WXUNUSED(height
), 
 120     // Necessary so it doesn't call wxChoice::SetSize 
 121     wxWindow::DoSetSize(x
, y
, width
, DoGetBestSize().y
, sizeFlags
); 
 125 // Already defined in include/motif/combobox.h 
 126 wxString 
wxComboBox::GetValue() const 
 128     char *s 
= XmComboBoxGetString ((Widget
) m_mainWidget
); 
 136         return wxEmptyString
; 
 140 void wxComboBox::SetValue(const wxString
& value
) 
 145         XmComboBoxSetString((Widget
)m_mainWidget
, value
.char_str()); 
 146         m_inSetValue 
= false; 
 150 void wxComboBox::SetString(unsigned int WXUNUSED(n
), const wxString
& WXUNUSED(s
)) 
 152     wxFAIL_MSG( wxT("wxComboBox::SetString only implemented for Motif 2.0") ); 
 155 // TODO auto-sorting is not supported by the code 
 156 int wxComboBox::DoInsertItems(const wxArrayStringsAdapter
& items
, 
 159                               wxClientDataType type
) 
 161     const unsigned int numItems 
= items
.GetCount(); 
 163     AllocClientData(numItems
); 
 164     for( unsigned int i 
= 0; i 
< numItems
; ++i
, ++pos 
) 
 166         wxXmString 
str( items
[i
].c_str() ); 
 167         XmComboBoxAddItem((Widget
) m_mainWidget
, str(), GetMotifPosition(pos
)); 
 168         wxChar
* copy 
= wxStrcpy(new wxChar
[items
[i
].length() + 1], items
[i
].c_str()); 
 169         m_stringList
.Insert(pos
, copy
); 
 171         InsertNewItemClientData(pos
, clientData
, i
, type
); 
 177 void wxComboBox::DoDeleteOneItem(unsigned int n
) 
 179     XmComboBoxDeletePos((Widget
) m_mainWidget
, n
+1); 
 180     wxStringList::Node 
*node 
= m_stringList
.Item(n
); 
 183         delete[] node
->GetData(); 
 186     wxControlWithItems::DoDeleteOneItem(n
); 
 190 void wxComboBox::Clear() 
 192     XmComboBoxDeleteAllItems((Widget
) m_mainWidget
); 
 193     m_stringList
.Clear(); 
 195     wxControlWithItems::DoClear(); 
 199 void wxComboBox::SetSelection (int n
) 
 201     XmComboBoxSelectPos((Widget
) m_mainWidget
, n
+1, False
); 
 204 int wxComboBox::GetSelection (void) const 
 206     int sel 
= XmComboBoxGetSelectedPos((Widget
) m_mainWidget
); 
 213 wxString 
wxComboBox::GetString(unsigned int n
) const 
 215     wxStringList::Node 
*node 
= m_stringList
.Item(n
); 
 217         return wxString(node
->GetData ()); 
 219         return wxEmptyString
; 
 222 int wxComboBox::FindString(const wxString
& s
, bool WXUNUSED(bCase
)) const 
 224     // FIXME: back to base class for not supported value of bCase 
 226     int *pos_list 
= NULL
; 
 228     wxXmString 
text( s 
); 
 229     bool found 
= (XmComboBoxGetMatchPos((Widget
) m_mainWidget
, 
 230         text(), &pos_list
, &count
) != 0); 
 232     if (found 
&& count 
> 0) 
 234         int pos 
= pos_list
[0] - 1; 
 242 void  wxComboBoxCallback (Widget 
WXUNUSED(w
), XtPointer clientData
, 
 243                           XmComboBoxSelectionCallbackStruct 
* cbs
) 
 245     wxComboBox 
*item 
= (wxComboBox 
*) clientData
; 
 249     case XmCR_SINGLE_SELECT
: 
 250     case XmCR_BROWSE_SELECT
: 
 252             wxCommandEvent 
event (wxEVT_COMMAND_COMBOBOX_SELECTED
, 
 254             event
.SetInt(cbs
->index 
- 1); 
 255             event
.SetString( item
->GetString ( event
.GetInt() ) ); 
 256             if ( item
->HasClientObjectData() ) 
 257                 event
.SetClientObject( item
->GetClientObject(cbs
->index 
- 1) ); 
 258             else if ( item
->HasClientUntypedData() ) 
 259                 event
.SetClientData( item
->GetClientData(cbs
->index 
- 1) ); 
 260             event
.SetExtraLong(true); 
 261             event
.SetEventObject(item
); 
 262             item
->ProcessCommand (event
); 
 265     case XmCR_VALUE_CHANGED
: 
 267             wxCommandEvent 
event (wxEVT_COMMAND_TEXT_UPDATED
, item
->GetId()); 
 269             event
.SetString( item
->GetValue() ); 
 270             event
.SetExtraLong(true); 
 271             event
.SetEventObject(item
); 
 272             item
->ProcessCommand (event
); 
 280 void wxComboBox::ChangeFont(bool keepOriginalSize
) 
 282     // Don't use the base class wxChoice's ChangeFont 
 283     wxWindow::ChangeFont(keepOriginalSize
); 
 286 void wxComboBox::ChangeBackgroundColour() 
 288     wxWindow::ChangeBackgroundColour(); 
 291 void wxComboBox::ChangeForegroundColour() 
 293     wxWindow::ChangeForegroundColour(); 
 296 wxSize 
wxComboBox::DoGetBestSize() const 
 298     if( (GetWindowStyle() & wxCB_DROPDOWN
) == wxCB_DROPDOWN 
|| 
 299         (GetWindowStyle() & wxCB_READONLY
) == wxCB_READONLY 
) 
 301         wxSize items 
= GetItemsSize(); 
 302         // FIXME arbitrary constants 
 303         return wxSize( ( items
.x 
? items
.x 
+ 50 : 120 ), 
 307         return wxWindow::DoGetBestSize(); 
 310 WXWidget 
wxComboBox::GetTextWidget() const 
 312     return (WXWidget
)XmComboBoxGetEditWidget((Widget
) m_mainWidget
); 
 315 #endif // XmVersion < 2000 
 317 #endif // wxUSE_COMBOBOX