]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/choice.cpp
* Added threads event propagation. Should compile on GTK (tested).
[wxWidgets.git] / src / gtk1 / choice.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: choice.cpp
3// Purpose:
4// Author: Robert Roebling
dbf858b5 5// Id: $Id$
01111366 6// Copyright: (c) 1998 Robert Roebling
29006414 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
10
11#ifdef __GNUG__
12#pragma implementation "choice.h"
13#endif
14
15#include "wx/choice.h"
16
83624f79
RR
17#include "gdk/gdk.h"
18#include "gtk/gtk.h"
19
66bd6b93
RR
20//-----------------------------------------------------------------------------
21// data
22//-----------------------------------------------------------------------------
23
24extern bool g_blockEventsOnDrag;
25
c801d85f 26//-----------------------------------------------------------------------------
e1e955e1 27// "activate"
c801d85f
KB
28//-----------------------------------------------------------------------------
29
66bd6b93 30static void gtk_choice_clicked_callback( GtkWidget *WXUNUSED(widget), wxChoice *choice )
c801d85f 31{
29006414
VZ
32 if (!choice->HasVMT())
33 return;
34
35 if (g_blockEventsOnDrag)
36 return;
37
47908e25 38 wxCommandEvent event(wxEVT_COMMAND_CHOICE_SELECTED, choice->GetId() );
c801d85f 39 event.SetInt( choice->GetSelection() );
29006414 40 event.SetString( choice->GetStringSelection() );
c801d85f 41 event.SetEventObject(choice);
47908e25 42 choice->GetEventHandler()->ProcessEvent(event);
6de97a3b 43}
c801d85f 44
e1e955e1
RR
45//-----------------------------------------------------------------------------
46// wxChoice
c801d85f
KB
47//-----------------------------------------------------------------------------
48
7f4dc78d 49IMPLEMENT_DYNAMIC_CLASS(wxChoice,wxControl)
c801d85f 50
fd0eed64 51wxChoice::wxChoice()
c801d85f 52{
6de97a3b 53}
c801d85f 54
debe6624 55bool wxChoice::Create( wxWindow *parent, wxWindowID id,
fd0eed64
RR
56 const wxPoint &pos, const wxSize &size,
57 int n, const wxString choices[],
58 long style, const wxValidator& validator, const wxString &name )
c801d85f 59{
fd0eed64 60 m_needParent = TRUE;
29006414 61
fd0eed64 62 PreCreation( parent, id, pos, size, style, name );
29006414 63
fd0eed64 64 SetValidator( validator );
6de97a3b 65
fd0eed64 66 m_widget = gtk_option_menu_new();
29006414
VZ
67
68 wxSize newSize(size);
69 if (newSize.x == -1)
70 newSize.x = 80;
71 if (newSize.y == -1)
72 newSize.y = 26;
fd0eed64 73 SetSize( newSize.x, newSize.y );
29006414 74
fd0eed64 75 GtkWidget *menu = gtk_menu_new();
29006414 76
fd0eed64
RR
77 for (int i = 0; i < n; i++)
78 {
79 m_clientDataList.Append( (wxObject*) NULL );
f5e27805 80 m_clientObjectList.Append( (wxObject*) NULL );
29006414 81
fd0eed64
RR
82 GtkWidget *item = gtk_menu_item_new_with_label( choices[i] );
83 gtk_menu_append( GTK_MENU(menu), item );
29006414 84
fd0eed64
RR
85 gtk_widget_realize( item );
86 gtk_widget_realize( GTK_BIN(item)->child );
29006414 87
fd0eed64 88 gtk_widget_show( item );
29006414
VZ
89
90 gtk_signal_connect( GTK_OBJECT( item ), "activate",
fd0eed64
RR
91 GTK_SIGNAL_FUNC(gtk_choice_clicked_callback), (gpointer*)this );
92 }
93 gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu );
29006414 94
fd0eed64 95 m_parent->AddChild( this );
6ca41e57 96
fd0eed64 97 (m_parent->m_insertCallback)( m_parent, this );
29006414 98
fd0eed64 99 PostCreation();
29006414 100
fd0eed64
RR
101 SetBackgroundColour( parent->GetBackgroundColour() );
102 SetForegroundColour( parent->GetForegroundColour() );
a7ac4461 103 SetFont( parent->GetFont() );
f96aa4d9 104
fd0eed64 105 Show( TRUE );
29006414 106
fd0eed64 107 return TRUE;
6de97a3b 108}
29006414 109
fd0eed64
RR
110wxChoice::~wxChoice()
111{
f5e27805 112 Clear();
fd0eed64
RR
113}
114
115void wxChoice::AppendCommon( const wxString &item )
116{
117 wxCHECK_RET( m_widget != NULL, "invalid choice" );
29006414 118
fd0eed64
RR
119 GtkWidget *menu = gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) );
120 GtkWidget *menu_item = gtk_menu_item_new_with_label( item );
29006414 121
fd0eed64 122 gtk_menu_append( GTK_MENU(menu), menu_item );
29006414 123
fd0eed64
RR
124 gtk_widget_realize( menu_item );
125 gtk_widget_realize( GTK_BIN(menu_item)->child );
29006414 126
fd0eed64 127 if (m_widgetStyle) ApplyWidgetStyle();
29006414
VZ
128
129 gtk_signal_connect( GTK_OBJECT( menu_item ), "activate",
fd0eed64 130 GTK_SIGNAL_FUNC(gtk_choice_clicked_callback), (gpointer*)this );
29006414 131
fd0eed64
RR
132 gtk_widget_show( menu_item );
133}
134
c801d85f
KB
135void wxChoice::Append( const wxString &item )
136{
f5e27805
RR
137 m_clientDataList.Append( (wxObject*) NULL );
138 m_clientObjectList.Append( (wxObject*) NULL );
29006414 139
fd0eed64
RR
140 AppendCommon( item );
141}
142
143void wxChoice::Append( const wxString &item, void *clientData )
144{
f5e27805
RR
145 m_clientDataList.Append( (wxObject*) clientData );
146 m_clientObjectList.Append( (wxObject*) NULL );
29006414 147
fd0eed64
RR
148 AppendCommon( item );
149}
150
151void wxChoice::Append( const wxString &item, wxClientData *clientData )
152{
f5e27805
RR
153 m_clientObjectList.Append( (wxObject*) clientData );
154 m_clientDataList.Append( (wxObject*) NULL );
29006414 155
fd0eed64
RR
156 AppendCommon( item );
157}
f96aa4d9 158
fd0eed64
RR
159void wxChoice::SetClientData( int n, void* clientData )
160{
161 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
29006414 162
fd0eed64
RR
163 wxNode *node = m_clientDataList.Nth( n );
164 if (!node) return;
29006414 165
f5e27805 166 node->SetData( (wxObject*) clientData );
fd0eed64
RR
167}
168
169void* wxChoice::GetClientData( int n )
170{
171 wxCHECK_MSG( m_widget != NULL, NULL, "invalid combobox" );
29006414 172
fd0eed64
RR
173 wxNode *node = m_clientDataList.Nth( n );
174 if (!node) return NULL;
29006414 175
f5e27805 176 return node->Data();
6de97a3b 177}
fd0eed64
RR
178
179void wxChoice::SetClientObject( int n, wxClientData* clientData )
180{
181 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
29006414 182
f5e27805 183 wxNode *node = m_clientObjectList.Nth( n );
fd0eed64 184 if (!node) return;
29006414 185
fd0eed64
RR
186 wxClientData *cd = (wxClientData*) node->Data();
187 if (cd) delete cd;
29006414 188
fd0eed64
RR
189 node->SetData( (wxObject*) clientData );
190}
191
192wxClientData* wxChoice::GetClientObject( int n )
193{
f5e27805 194 wxCHECK_MSG( m_widget != NULL, (wxClientData*) NULL, "invalid combobox" );
29006414 195
f5e27805 196 wxNode *node = m_clientObjectList.Nth( n );
fd0eed64 197 if (!node) return (wxClientData*) NULL;
29006414 198
fd0eed64
RR
199 return (wxClientData*) node->Data();
200}
29006414 201
fd0eed64 202void wxChoice::Clear()
c801d85f 203{
fd0eed64 204 wxCHECK_RET( m_widget != NULL, "invalid choice" );
f96aa4d9 205
fd0eed64
RR
206 gtk_option_menu_remove_menu( GTK_OPTION_MENU(m_widget) );
207 GtkWidget *menu = gtk_menu_new();
208 gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu );
29006414 209
f5e27805 210 wxNode *node = m_clientObjectList.First();
fd0eed64
RR
211 while (node)
212 {
213 wxClientData *cd = (wxClientData*)node->Data();
214 if (cd) delete cd;
215 node = node->Next();
216 }
f5e27805 217 m_clientObjectList.Clear();
29006414 218
fd0eed64 219 m_clientDataList.Clear();
6de97a3b 220}
c801d85f 221
2f6407b9
RR
222void wxChoice::Delete( int WXUNUSED(n) )
223{
fd0eed64 224 wxFAIL_MSG( "wxChoice:Delete not implemented" );
2f6407b9
RR
225}
226
c801d85f
KB
227int wxChoice::FindString( const wxString &string ) const
228{
fd0eed64
RR
229 wxCHECK_MSG( m_widget != NULL, -1, "invalid choice" );
230
231 // If you read this code once and you think you understand
232 // it, then you are very wrong. Robert Roebling.
29006414 233
fd0eed64
RR
234 GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
235 int count = 0;
236 GList *child = menu_shell->children;
237 while (child)
238 {
239 GtkBin *bin = GTK_BIN( child->data );
240 GtkLabel *label = (GtkLabel *) NULL;
241 if (bin->child) label = GTK_LABEL(bin->child);
242 if (!label) label = GTK_LABEL( GTK_BUTTON(m_widget)->child );
29006414 243
fd0eed64 244 wxASSERT_MSG( label != NULL , "wxChoice: invalid label" );
29006414
VZ
245
246 if (string == label->label)
247 return count;
248
fd0eed64
RR
249 child = child->next;
250 count++;
251 }
29006414 252
fd0eed64 253 return -1;
6de97a3b 254}
c801d85f 255
fd0eed64 256int wxChoice::GetColumns() const
c801d85f 257{
fd0eed64 258 return 1;
6de97a3b 259}
c801d85f 260
fd0eed64 261int wxChoice::GetSelection()
c801d85f 262{
fd0eed64
RR
263 wxCHECK_MSG( m_widget != NULL, -1, "invalid choice" );
264
265 GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
266 int count = 0;
267 GList *child = menu_shell->children;
268 while (child)
269 {
270 GtkBin *bin = GTK_BIN( child->data );
271 if (!bin->child) return count;
272 child = child->next;
273 count++;
274 }
29006414 275
fd0eed64 276 wxFAIL_MSG( "wxChoice: no selection" );
29006414 277
fd0eed64 278 return -1;
6de97a3b 279}
c801d85f 280
debe6624 281wxString wxChoice::GetString( int n ) const
c801d85f 282{
fd0eed64
RR
283 wxCHECK_MSG( m_widget != NULL, "", "invalid choice" );
284
285 GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
286 int count = 0;
287 GList *child = menu_shell->children;
288 while (child)
c801d85f 289 {
fd0eed64
RR
290 GtkBin *bin = GTK_BIN( child->data );
291 if (count == n)
292 {
293 GtkLabel *label = (GtkLabel *) NULL;
294 if (bin->child) label = GTK_LABEL(bin->child);
295 if (!label) label = GTK_LABEL( GTK_BUTTON(m_widget)->child );
29006414 296
fd0eed64 297 wxASSERT_MSG( label != NULL , "wxChoice: invalid label" );
29006414 298
fd0eed64
RR
299 return label->label;
300 }
301 child = child->next;
302 count++;
6de97a3b 303 }
29006414
VZ
304
305 wxFAIL_MSG( "wxChoice: invalid index in GetString()" );
306
fd0eed64 307 return "";
6de97a3b 308}
c801d85f 309
fd0eed64 310wxString wxChoice::GetStringSelection() const
c801d85f 311{
fd0eed64 312 wxCHECK_MSG( m_widget != NULL, "", "invalid choice" );
f96aa4d9 313
fd0eed64 314 GtkLabel *label = GTK_LABEL( GTK_BUTTON(m_widget)->child );
29006414 315
fd0eed64 316 wxASSERT_MSG( label != NULL , "wxChoice: invalid label" );
29006414 317
fd0eed64 318 return label->label;
6de97a3b 319}
c801d85f 320
fd0eed64 321int wxChoice::Number() const
c801d85f 322{
fd0eed64
RR
323 wxCHECK_MSG( m_widget != NULL, 0, "invalid choice" );
324
325 GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
326 int count = 0;
327 GList *child = menu_shell->children;
328 while (child)
329 {
330 count++;
331 child = child->next;
332 }
333 return count;
6de97a3b 334}
c801d85f 335
debe6624 336void wxChoice::SetColumns( int WXUNUSED(n) )
c801d85f 337{
6de97a3b 338}
c801d85f 339
debe6624 340void wxChoice::SetSelection( int n )
c801d85f 341{
fd0eed64 342 wxCHECK_RET( m_widget != NULL, "invalid choice" );
f96aa4d9 343
fd0eed64
RR
344 int tmp = n;
345 gtk_option_menu_set_history( GTK_OPTION_MENU(m_widget), (gint)tmp );
29006414 346
fd0eed64 347 gtk_choice_clicked_callback( (GtkWidget *) NULL, this );
6de97a3b 348}
c801d85f
KB
349
350void wxChoice::SetStringSelection( const wxString &string )
351{
fd0eed64 352 wxCHECK_RET( m_widget != NULL, "invalid choice" );
f96aa4d9 353
fd0eed64
RR
354 int n = FindString( string );
355 if (n != -1) SetSelection( n );
6de97a3b 356}
c801d85f 357
58614078 358void wxChoice::ApplyWidgetStyle()
868a2826 359{
fd0eed64 360 SetWidgetStyle();
29006414 361
fd0eed64 362 GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
29006414 363
fd0eed64
RR
364 gtk_widget_set_style( m_widget, m_widgetStyle );
365 gtk_widget_set_style( GTK_WIDGET( menu_shell ), m_widgetStyle );
29006414 366
fd0eed64
RR
367 GList *child = menu_shell->children;
368 while (child)
369 {
370 gtk_widget_set_style( GTK_WIDGET( child->data ), m_widgetStyle );
29006414 371
fd0eed64
RR
372 GtkBin *bin = GTK_BIN( child->data );
373 GtkWidget *label = (GtkWidget *) NULL;
374 if (bin->child) label = bin->child;
375 if (!label) label = GTK_BUTTON(m_widget)->child;
29006414 376
fd0eed64 377 gtk_widget_set_style( label, m_widgetStyle );
29006414 378
fd0eed64
RR
379 child = child->next;
380 }
f96aa4d9
RR
381}
382