1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   7 // Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem 
   8 // Licence:     wxWindows licence 
   9 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "listbox.h" 
  16 #include "wx/dynarray.h" 
  17 #include "wx/listbox.h" 
  19 //----------------------------------------------------------------------------- 
  21 //----------------------------------------------------------------------------- 
  23 extern bool   g_blockEventsOnDrag
; 
  25 //----------------------------------------------------------------------------- 
  27 //----------------------------------------------------------------------------- 
  29 static void gtk_listitem_select_callback( GtkWidget 
*widget
, wxListBox 
*listbox 
) 
  31   if (!listbox
->HasVMT()) return; 
  32   if (g_blockEventsOnDrag
) return; 
  34   wxCommandEvent 
event(wxEVT_COMMAND_LISTBOX_SELECTED
, listbox
->GetId() ); 
  36   event
.SetInt( listbox
->GetIndex( widget 
) ); 
  38   GtkBin 
*bin 
= GTK_BIN( widget 
); 
  39   GtkLabel 
*label 
= GTK_LABEL( bin
->child 
); 
  40   wxString 
tmp( label
->label 
); 
  41   event
.SetString( WXSTRINGCAST(tmp
) ); 
  42   event
.SetEventObject( listbox 
); 
  44   listbox
->GetEventHandler()->ProcessEvent( event 
); 
  47 //----------------------------------------------------------------------------- 
  49 IMPLEMENT_DYNAMIC_CLASS(wxListBox
,wxControl
) 
  51 wxListBox::wxListBox(void) 
  56 wxListBox::wxListBox( wxWindow 
*parent
, wxWindowID id
,  
  57       const wxPoint 
&pos
, const wxSize 
&size
,  
  58       int n
, const wxString choices
[], 
  59       long style
, const wxString 
&name 
) 
  61   Create( parent
, id
, pos
, size
, n
, choices
, style
, name 
); 
  64 bool wxListBox::Create( wxWindow 
*parent
, wxWindowID id
,  
  65       const wxPoint 
&pos
, const wxSize 
&size
,  
  66       int n
, const wxString choices
[], 
  67       long style
, const wxString 
&name 
) 
  71   PreCreation( parent
, id
, pos
, size
, style
, name 
); 
  73   m_widget 
= gtk_scrolled_window_new( NULL
, NULL 
); 
  74   gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(m_widget
), 
  75     GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC 
); 
  77   m_list 
= GTK_LIST( gtk_list_new() ); 
  79   // @@ what's the difference between BROWSE and SINGLE? 
  80   GtkSelectionMode mode 
= GTK_SELECTION_BROWSE
; 
  81   if ( style 
& wxLB_MULTIPLE 
) 
  82     mode 
= GTK_SELECTION_MULTIPLE
; 
  83   else if ( style 
& wxLB_EXTENDED 
) 
  84     mode 
= GTK_SELECTION_EXTENDED
; 
  86   gtk_list_set_selection_mode( GTK_LIST(m_list
), mode 
); 
  88   gtk_container_add (GTK_CONTAINER(m_widget
), GTK_WIDGET(m_list
) ); 
  89   gtk_widget_show( GTK_WIDGET(m_list
) ); 
  91   for (int i 
= 0; i 
< n
; i
++) 
  94     list_item 
= gtk_list_item_new_with_label( choices
[i
] );  
  96     gtk_container_add( GTK_CONTAINER(m_list
), list_item 
); 
  98     gtk_signal_connect( GTK_OBJECT(list_item
), "select",  
  99       GTK_SIGNAL_FUNC(gtk_listitem_select_callback
), (gpointer
)this ); 
 101     m_clientData
.Append( (wxObject
*)NULL 
); 
 103     gtk_widget_show( list_item 
); 
 108   gtk_widget_realize( GTK_WIDGET(m_list
) ); 
 115 void wxListBox::Append( const wxString 
&item 
) 
 117   GtkWidget 
*list_item
; 
 118   list_item 
= gtk_list_item_new_with_label( item 
);  
 120  gtk_signal_connect( GTK_OBJECT(list_item
), "select",  
 121     GTK_SIGNAL_FUNC(gtk_listitem_select_callback
), (gpointer
)this ); 
 123   gtk_container_add( GTK_CONTAINER(m_list
), list_item 
); 
 125   m_clientData
.Append( (wxObject
*)NULL 
); 
 127   gtk_widget_show( list_item 
); 
 130 void wxListBox::Append( const wxString 
&item
, char *clientData 
) 
 132   GtkWidget 
*list_item
; 
 133   list_item 
= gtk_list_item_new_with_label( item 
);  
 135  gtk_signal_connect( GTK_OBJECT(list_item
), "select",  
 136     GTK_SIGNAL_FUNC(gtk_listitem_select_callback
), (gpointer
)this ); 
 138   gtk_container_add( GTK_CONTAINER(m_list
), list_item 
); 
 140   m_clientData
.Append( (wxObject
*)clientData 
); 
 142   gtk_widget_show( list_item 
); 
 145 void wxListBox::Clear(void) 
 147   gtk_list_clear_items( m_list
, 0, Number() ); 
 149   m_clientData
.Clear(); 
 152 void wxListBox::Delete( int n 
) 
 154   gtk_list_clear_items( m_list
, n
, n 
); 
 156   wxNode 
*node 
= m_clientData
.Nth( n 
); 
 159     wxFAIL_MSG("wxListBox::Delete wrong index"); 
 162     m_clientData
.DeleteNode( node 
); 
 165 void wxListBox::Deselect( int n 
) 
 167   gtk_list_unselect_item( m_list
, n 
); 
 170 int wxListBox::FindString( const wxString 
&item 
) const 
 172   GList 
*child 
= m_list
->children
; 
 176     GtkBin 
*bin 
= GTK_BIN( child
->data 
); 
 177     GtkLabel 
*label 
= GTK_LABEL( bin
->child 
); 
 178     if (item 
== label
->label
) return count
; 
 185 char *wxListBox::GetClientData( int n 
) const 
 187   wxNode 
*node 
= m_clientData
.Nth( n 
); 
 188   if (node
) return ((char*)node
->Data()); 
 192 int wxListBox::GetSelection(void) const 
 194   GList 
*selection 
= m_list
->selection
; 
 197     GList 
*child 
= m_list
->children
; 
 201       if (child
->data 
== selection
->data
) return count
; 
 209 int wxListBox::GetSelections(wxArrayInt
& aSelections
) const 
 211   // get the number of selected items first 
 212   GList 
*child 
= m_list
->children
; 
 214   for ( child 
= m_list
->children
; child 
!= NULL
; child 
= child
->next 
) { 
 215     if ( GTK_WIDGET(child
->data
)->state 
== GTK_STATE_SELECTED 
)  
 223     aSelections
.Alloc(count
); // optimization attempt 
 225     for ( child 
= m_list
->children
; child 
!= NULL
; child 
= child
->next
, i
++ ) { 
 226       if ( GTK_WIDGET(child
->data
)->state 
== GTK_STATE_SELECTED 
)  
 234 wxString 
wxListBox::GetString( int n 
) const 
 236   GList 
*child 
= g_list_nth( m_list
->children
, n 
); 
 239     GtkBin 
*bin 
= GTK_BIN( child
->data 
); 
 240     GtkLabel 
*label 
= GTK_LABEL( bin
->child 
); 
 246 wxString 
wxListBox::GetStringSelection(void) const 
 248   GList 
*selection 
= m_list
->selection
; 
 251     GtkBin 
*bin 
= GTK_BIN( selection
->data 
); 
 252     wxString tmp 
= GTK_LABEL( bin
->child 
)->label
; 
 258 int wxListBox::Number(void) 
 260   GList 
*child 
= m_list
->children
; 
 262   while (child
) { count
++; child 
= child
->next
; }; 
 266 bool wxListBox::Selected( int n 
) 
 268   GList 
*target 
= g_list_nth( m_list
->children
, n 
); 
 271     GList 
*child 
= m_list
->selection
; 
 274       if (child
->data 
== target
->data
) return TRUE
; 
 281 void wxListBox::Set( int WXUNUSED(n
), const wxString 
*WXUNUSED(choices
) ) 
 285 void wxListBox::SetClientData( int n
, char *clientData 
) 
 287   wxNode 
*node 
= m_clientData
.Nth( n 
); 
 288   if (node
) node
->SetData( (wxObject
*)clientData 
); 
 291 void wxListBox::SetFirstItem( int WXUNUSED(n
) ) 
 295 void wxListBox::SetFirstItem( const wxString 
&WXUNUSED(item
) ) 
 299 void wxListBox::SetSelection( int n
, bool select 
) 
 302     gtk_list_select_item( m_list
, n 
); 
 304     gtk_list_unselect_item( m_list
, n 
); 
 307 void wxListBox::SetString( int WXUNUSED(n
), const wxString 
&WXUNUSED(string
) ) 
 311 void wxListBox::SetStringSelection( const wxString 
&string
, bool select 
) 
 313   SetSelection( FindString(string
), select 
); 
 316 int wxListBox::GetIndex( GtkWidget 
*item 
) const 
 320     GList 
*child 
= m_list
->children
; 
 324       if (GTK_WIDGET(child
->data
) == item
) return count
; 
 332 GtkWidget 
*wxListBox::GetDropTargetWidget(void) 
 334   return GTK_WIDGET(m_list
);