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" 
  21 //----------------------------------------------------------------------------- 
  23 //----------------------------------------------------------------------------- 
  25 extern bool   g_blockEventsOnDrag
; 
  27 //----------------------------------------------------------------------------- 
  28 // "select" and "deselect" 
  29 //----------------------------------------------------------------------------- 
  31 static void gtk_listitem_select_callback( GtkWidget 
*WXUNUSED(widget
), wxListBox 
*listbox 
) 
  33   if (!listbox
->HasVMT()) return; 
  34   if (g_blockEventsOnDrag
) return; 
  36   wxCommandEvent 
event(wxEVT_COMMAND_LISTBOX_SELECTED
, listbox
->GetId() ); 
  38     wxArrayInt aSelections
; 
  39     int count 
= listbox
->GetSelections(aSelections
); 
  42       event
.m_commandInt 
= aSelections
[0] ; 
  43       event
.m_clientData 
= listbox
->GetClientData(event
.m_commandInt
); 
  44       wxString 
str(listbox
->GetString(event
.m_commandInt
)); 
  46         event
.m_commandString 
= copystring((char *)(const char *)str
); 
  50       event
.m_commandInt 
= -1 ; 
  51       event
.m_commandString 
= copystring("") ; 
  54   event
.SetEventObject( listbox 
); 
  56   listbox
->GetEventHandler()->ProcessEvent( event 
); 
  57   if (event
.m_commandString
) delete[] event
.m_commandString 
; 
  60 //----------------------------------------------------------------------------- 
  62 //----------------------------------------------------------------------------- 
  64 IMPLEMENT_DYNAMIC_CLASS(wxListBox
,wxControl
) 
  66 wxListBox::wxListBox(void) 
  68   m_list 
= (GtkList 
*) NULL
; 
  71 bool wxListBox::Create( wxWindow 
*parent
, wxWindowID id
,  
  72       const wxPoint 
&pos
, const wxSize 
&size
,  
  73       int n
, const wxString choices
[], 
  74       long style
, const wxValidator
& validator
, const wxString 
&name 
) 
  78   PreCreation( parent
, id
, pos
, size
, style
, name 
); 
  80   SetValidator( validator 
); 
  82   m_widget 
= gtk_scrolled_window_new( (GtkAdjustment 
*) NULL
, (GtkAdjustment 
*) NULL 
); 
  83   gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(m_widget
), 
  84     GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC 
); 
  86   m_list 
= GTK_LIST( gtk_list_new() ); 
  88   GtkSelectionMode mode 
= GTK_SELECTION_SINGLE
; 
  89   if (style 
& wxLB_MULTIPLE
) 
  90     mode 
= GTK_SELECTION_MULTIPLE
; 
  91   else if (style 
& wxLB_EXTENDED
) 
  92     mode 
= GTK_SELECTION_EXTENDED
; 
  94   gtk_list_set_selection_mode( GTK_LIST(m_list
), mode 
); 
  96   gtk_container_add (GTK_CONTAINER(m_widget
), GTK_WIDGET(m_list
) ); 
  97   gtk_widget_show( GTK_WIDGET(m_list
) ); 
  99   for (int i 
= 0; i 
< n
; i
++) 
 101     GtkWidget 
*list_item
; 
 102     list_item 
= gtk_list_item_new_with_label( choices
[i
] );  
 104     gtk_container_add( GTK_CONTAINER(m_list
), list_item 
); 
 106     gtk_signal_connect( GTK_OBJECT(list_item
), "select",  
 107       GTK_SIGNAL_FUNC(gtk_listitem_select_callback
), (gpointer
)this ); 
 109     if (style 
& wxLB_MULTIPLE
) 
 110       gtk_signal_connect( GTK_OBJECT(list_item
), "deselect",  
 111         GTK_SIGNAL_FUNC(gtk_listitem_select_callback
), (gpointer
)this ); 
 113     m_clientData
.Append( (wxObject
*)NULL 
); 
 115     gtk_widget_show( list_item 
); 
 120   gtk_widget_realize( GTK_WIDGET(m_list
) ); 
 127 void wxListBox::Append( const wxString 
&item 
) 
 129   Append( item
, (char*)NULL 
); 
 132 void wxListBox::Append( const wxString 
&item
, char *clientData 
) 
 134   GtkWidget 
*list_item 
= gtk_list_item_new_with_label( item 
);  
 138     GtkBin 
*bin 
= GTK_BIN( list_item 
); 
 139     gtk_widget_set_style( bin
->child
,  
 141         gtk_widget_get_style( m_widget 
) ) );  
 144   gtk_signal_connect( GTK_OBJECT(list_item
), "select",  
 145     GTK_SIGNAL_FUNC(gtk_listitem_select_callback
), (gpointer
)this ); 
 147   if (GetWindowStyleFlag() & wxLB_MULTIPLE
) 
 148     gtk_signal_connect( GTK_OBJECT(list_item
), "deselect",  
 149       GTK_SIGNAL_FUNC(gtk_listitem_select_callback
), (gpointer
)this ); 
 151   m_clientData
.Append( (wxObject
*)clientData 
); 
 153   gtk_container_add( GTK_CONTAINER(m_list
), list_item 
); 
 155   gtk_widget_show( list_item 
); 
 157   ConnectWidget( list_item 
); 
 159   ConnectDnDWidget( list_item 
); 
 163 void wxListBox::Clear(void) 
 165   gtk_list_clear_items( m_list
, 0, Number() ); 
 167   m_clientData
.Clear(); 
 170 void wxListBox::Delete( int n 
) 
 172   GList 
*child 
= g_list_nth( m_list
->children
, n 
); 
 176     wxFAIL_MSG("wrong listbox index"); 
 180   GList 
*list 
= g_list_append( NULL
, child
->data 
); 
 181   gtk_list_remove_items( m_list
, list 
); 
 184   wxNode 
*node 
= m_clientData
.Nth( n 
); 
 187     wxFAIL_MSG("wrong listbox index"); 
 190     m_clientData
.DeleteNode( node 
); 
 193 void wxListBox::Deselect( int n 
) 
 195   gtk_list_unselect_item( m_list
, n 
); 
 198 int wxListBox::FindString( const wxString 
&item 
) const 
 200   GList 
*child 
= m_list
->children
; 
 204     GtkBin 
*bin 
= GTK_BIN( child
->data 
); 
 205     GtkLabel 
*label 
= GTK_LABEL( bin
->child 
); 
 206     if (item 
== label
->label
) return count
; 
 210   wxFAIL_MSG("wrong listbox index"); 
 214 char *wxListBox::GetClientData( int n 
) const 
 216   wxNode 
*node 
= m_clientData
.Nth( n 
); 
 217   if (node
) return ((char*)node
->Data()); 
 219   wxFAIL_MSG("wrong listbox index"); 
 220   return (char *) NULL
; 
 223 int wxListBox::GetSelection(void) const 
 225   GList 
*selection 
= m_list
->selection
; 
 228     GList 
*child 
= m_list
->children
; 
 232       if (child
->data 
== selection
->data
) return count
; 
 237   wxFAIL_MSG("wrong listbox index"); 
 241 int wxListBox::GetSelections(wxArrayInt
& aSelections
) const 
 243   // get the number of selected items first 
 244   GList 
*child 
= m_list
->children
; 
 246   for ( child 
= m_list
->children
; child 
!= NULL
; child 
= child
->next 
)  
 248     if ( GTK_WIDGET(child
->data
)->state 
== GTK_STATE_SELECTED 
)  
 256     aSelections
.Alloc(count
); // optimization attempt 
 258     for ( child 
= m_list
->children
; child 
!= NULL
; child 
= child
->next
, i
++ )  
 260       if ( GTK_WIDGET(child
->data
)->state 
== GTK_STATE_SELECTED 
)  
 268 wxString 
wxListBox::GetString( int n 
) const 
 270   GList 
*child 
= g_list_nth( m_list
->children
, n 
); 
 273     GtkBin 
*bin 
= GTK_BIN( child
->data 
); 
 274     GtkLabel 
*label 
= GTK_LABEL( bin
->child 
); 
 277   wxFAIL_MSG("wrong listbox index"); 
 281 wxString 
wxListBox::GetStringSelection(void) const 
 283   GList 
*selection 
= m_list
->selection
; 
 286     GtkBin 
*bin 
= GTK_BIN( selection
->data 
); 
 287     wxString tmp 
= GTK_LABEL( bin
->child 
)->label
; 
 290   wxFAIL_MSG("no listbox selection available"); 
 294 int wxListBox::Number(void) 
 296   GList 
*child 
= m_list
->children
; 
 298   while (child
) { count
++; child 
= child
->next
; } 
 302 bool wxListBox::Selected( int n 
) 
 304   GList 
*target 
= g_list_nth( m_list
->children
, n 
); 
 307     GList 
*child 
= m_list
->selection
; 
 310       if (child
->data 
== target
->data
) return TRUE
; 
 314   wxFAIL_MSG("wrong listbox index"); 
 318 void wxListBox::Set( int WXUNUSED(n
), const wxString 
*WXUNUSED(choices
) ) 
 320   wxFAIL_MSG("wxListBox::Set not implemented"); 
 323 void wxListBox::SetClientData( int n
, char *clientData 
) 
 325   wxNode 
*node 
= m_clientData
.Nth( n 
); 
 328     node
->SetData( (wxObject
*)clientData 
); 
 332     wxFAIL_MSG("wrong listbox index"); 
 336 void wxListBox::SetFirstItem( int WXUNUSED(n
) ) 
 338   wxFAIL_MSG("wxListBox::SetFirstItem not implemented"); 
 341 void wxListBox::SetFirstItem( const wxString 
&WXUNUSED(item
) ) 
 343   wxFAIL_MSG("wxListBox::SetFirstItem not implemented"); 
 346 void wxListBox::SetSelection( int n
, bool select 
) 
 349     gtk_list_select_item( m_list
, n 
); 
 351     gtk_list_unselect_item( m_list
, n 
); 
 354 void wxListBox::SetString( int n
, const wxString 
&string 
) 
 356   GList 
*child 
= g_list_nth( m_list
->children
, n 
); 
 359     GtkBin 
*bin 
= GTK_BIN( child
->data 
); 
 360     GtkLabel 
*label 
= GTK_LABEL( bin
->child 
); 
 361     gtk_label_set( label
, string 
); 
 365     wxFAIL_MSG("wrong listbox index"); 
 369 void wxListBox::SetStringSelection( const wxString 
&string
, bool select 
) 
 371   SetSelection( FindString(string
), select 
); 
 374 int wxListBox::GetIndex( GtkWidget 
*item 
) const 
 378     GList 
*child 
= m_list
->children
; 
 382       if (GTK_WIDGET(child
->data
) == item
) return count
; 
 390 void wxListBox::SetDropTarget( wxDropTarget 
*dropTarget 
) 
 392   GList 
*child 
= m_list
->children
; 
 395     DisconnectDnDWidget( GTK_WIDGET( child
->data 
) ); 
 399   wxWindow::SetDropTarget( dropTarget  
); 
 401   child 
= m_list
->children
; 
 404     ConnectDnDWidget( GTK_WIDGET( child
->data 
) ); 
 409 GtkWidget 
*wxListBox::GetConnectWidget(void) 
 411   return GTK_WIDGET(m_list
); 
 414 void wxListBox::SetFont( const wxFont 
&font 
) 
 416   wxWindow::SetFont( font 
); 
 418   GList 
*child 
= m_list
->children
; 
 421     GtkBin 
*bin 
= (GtkBin
*) child
->data
; 
 422     gtk_widget_set_style( bin
->child
,  
 424         gtk_widget_get_style( m_widget 
) ) );