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