Big color update with the newest information
[wxWidgets.git] / src / gtk1 / choice.cpp
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 //-----------------------------------------------------------------------------
18 // data
19 //-----------------------------------------------------------------------------
20
21 extern bool g_blockEventsOnDrag;
22
23 //-----------------------------------------------------------------------------
24 // "activate"
25 //-----------------------------------------------------------------------------
26
27 static void gtk_choice_clicked_callback( GtkWidget *WXUNUSED(widget), wxChoice *choice )
28 {
29 if (!choice->HasVMT()) return;
30 if (g_blockEventsOnDrag) return;
31
32 wxCommandEvent event(wxEVT_COMMAND_CHOICE_SELECTED, choice->GetId() );
33 event.SetInt( choice->GetSelection() );
34 wxString tmp( choice->GetStringSelection() );
35 event.SetString( WXSTRINGCAST(tmp) );
36 event.SetEventObject(choice);
37 choice->GetEventHandler()->ProcessEvent(event);
38 }
39
40 //-----------------------------------------------------------------------------
41 // wxChoice
42 //-----------------------------------------------------------------------------
43
44 IMPLEMENT_DYNAMIC_CLASS(wxChoice,wxControl)
45
46 wxChoice::wxChoice(void)
47 {
48 }
49
50 bool wxChoice::Create( wxWindow *parent, wxWindowID id,
51 const wxPoint &pos, const wxSize &size,
52 int n, const wxString choices[],
53 long style, const wxValidator& validator, const wxString &name )
54 {
55 m_needParent = TRUE;
56
57 PreCreation( parent, id, pos, size, style, name );
58
59 SetValidator( validator );
60
61 m_widget = gtk_option_menu_new();
62
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 );
67
68 GtkWidget *menu = gtk_menu_new();
69
70 for (int i = 0; i < n; i++)
71 {
72 GtkWidget *item = gtk_menu_item_new_with_label( choices[i] );
73 gtk_menu_append( GTK_MENU(menu), item );
74
75 gtk_widget_realize( item );
76 gtk_widget_realize( GTK_BIN(item)->child );
77
78 gtk_widget_show( item );
79
80 gtk_signal_connect( GTK_OBJECT( item ), "activate",
81 GTK_SIGNAL_FUNC(gtk_choice_clicked_callback), (gpointer*)this );
82 }
83 gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu );
84
85 PostCreation();
86
87 SetBackgroundColour( parent->GetBackgroundColour() );
88 SetForegroundColour( parent->GetForegroundColour() );
89
90 Show( TRUE );
91
92 return TRUE;
93 }
94
95 void wxChoice::Append( const wxString &item )
96 {
97 wxCHECK_RET( m_widget != NULL, "invalid choice" );
98
99 GtkWidget *menu = gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) );
100 GtkWidget *menu_item = gtk_menu_item_new_with_label( item );
101
102 gtk_menu_append( GTK_MENU(menu), menu_item );
103
104 gtk_widget_realize( menu_item );
105 gtk_widget_realize( GTK_BIN(menu_item)->child );
106
107 if (m_widgetStyle) ApplyWidgetStyle();
108
109 gtk_signal_connect( GTK_OBJECT( menu_item ), "activate",
110 GTK_SIGNAL_FUNC(gtk_choice_clicked_callback), (gpointer*)this );
111
112 gtk_widget_show( menu_item );
113 }
114
115 void wxChoice::Clear(void)
116 {
117 wxCHECK_RET( m_widget != NULL, "invalid choice" );
118
119 gtk_option_menu_remove_menu( GTK_OPTION_MENU(m_widget) );
120 GtkWidget *menu = gtk_menu_new();
121 gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu );
122 }
123
124 void wxChoice::Delete( int WXUNUSED(n) )
125 {
126 wxFAIL_MSG( "wxChoice:Delete not implemented" );
127 }
128
129 int wxChoice::FindString( const wxString &string ) const
130 {
131 wxCHECK_MSG( m_widget != NULL, -1, "invalid choice" );
132
133 // If you read this code once and you think you understand
134 // it, then you are very wrong. Robert Roebling.
135
136 GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
137 int count = 0;
138 GList *child = menu_shell->children;
139 while (child)
140 {
141 GtkBin *bin = GTK_BIN( child->data );
142 GtkLabel *label = (GtkLabel *) NULL;
143 if (bin->child) label = GTK_LABEL(bin->child);
144 if (!label) label = GTK_LABEL( GTK_BUTTON(m_widget)->child );
145
146 wxASSERT_MSG( label != NULL , "wxChoice: invalid label" );
147
148 if (string == label->label) return count;
149 child = child->next;
150 count++;
151 }
152
153 wxFAIL_MSG( "wxChoice: string not found" );
154
155 return -1;
156 }
157
158 int wxChoice::GetColumns(void) const
159 {
160 return 1;
161 }
162
163 int wxChoice::GetSelection(void)
164 {
165 wxCHECK_MSG( m_widget != NULL, -1, "invalid choice" );
166
167 GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
168 int count = 0;
169 GList *child = menu_shell->children;
170 while (child)
171 {
172 GtkBin *bin = GTK_BIN( child->data );
173 if (!bin->child) return count;
174 child = child->next;
175 count++;
176 }
177
178 wxFAIL_MSG( "wxChoice: no selection" );
179
180 return -1;
181 }
182
183 wxString wxChoice::GetString( int n ) const
184 {
185 wxCHECK_MSG( m_widget != NULL, "", "invalid choice" );
186
187 GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
188 int count = 0;
189 GList *child = menu_shell->children;
190 while (child)
191 {
192 GtkBin *bin = GTK_BIN( child->data );
193 if (count == n)
194 {
195 GtkLabel *label = (GtkLabel *) NULL;
196 if (bin->child) label = GTK_LABEL(bin->child);
197 if (!label) label = GTK_LABEL( GTK_BUTTON(m_widget)->child );
198
199 wxASSERT_MSG( label != NULL , "wxChoice: invalid label" );
200
201 return label->label;
202 }
203 child = child->next;
204 count++;
205 }
206
207 wxFAIL_MSG( "wxChoice: string not found" );
208
209 return "";
210 }
211
212 wxString wxChoice::GetStringSelection(void) const
213 {
214 wxCHECK_MSG( m_widget != NULL, "", "invalid choice" );
215
216 GtkLabel *label = GTK_LABEL( GTK_BUTTON(m_widget)->child );
217
218 wxASSERT_MSG( label != NULL , "wxChoice: invalid label" );
219
220 return label->label;
221 }
222
223 int wxChoice::Number(void) const
224 {
225 wxCHECK_MSG( m_widget != NULL, 0, "invalid choice" );
226
227 GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
228 int count = 0;
229 GList *child = menu_shell->children;
230 while (child)
231 {
232 count++;
233 child = child->next;
234 }
235 return count;
236 }
237
238 void wxChoice::SetColumns( int WXUNUSED(n) )
239 {
240 }
241
242 void wxChoice::SetSelection( int n )
243 {
244 wxCHECK_RET( m_widget != NULL, "invalid choice" );
245
246 int tmp = n;
247 gtk_option_menu_set_history( GTK_OPTION_MENU(m_widget), (gint)tmp );
248
249 gtk_choice_clicked_callback( (GtkWidget *) NULL, this );
250 }
251
252 void wxChoice::SetStringSelection( const wxString &string )
253 {
254 wxCHECK_RET( m_widget != NULL, "invalid choice" );
255
256 int n = FindString( string );
257 if (n != -1) SetSelection( n );
258 }
259
260 void wxChoice::ApplyWidgetStyle()
261 {
262 SetWidgetStyle();
263
264 GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
265
266 gtk_widget_set_style( m_widget, m_widgetStyle );
267 gtk_widget_set_style( GTK_WIDGET( menu_shell ), m_widgetStyle );
268
269 GList *child = menu_shell->children;
270 while (child)
271 {
272 gtk_widget_set_style( GTK_WIDGET( child->data ), m_widgetStyle );
273
274 GtkBin *bin = GTK_BIN( child->data );
275 GtkWidget *label = (GtkWidget *) NULL;
276 if (bin->child) label = bin->child;
277 if (!label) label = GTK_BUTTON(m_widget)->child;
278
279 gtk_widget_set_style( label, m_widgetStyle );
280
281 child = child->next;
282 }
283 }
284