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