Added background colour again
[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_signal_connect( GTK_OBJECT( item ), "activate",
74 GTK_SIGNAL_FUNC(gtk_choice_clicked_callback), (gpointer*)this );
75
76 gtk_menu_append( GTK_MENU(menu), item );
77
78 gtk_widget_show( item );
79 gtk_widget_realize( item );
80 gtk_widget_realize( GTK_BIN(item)->child );
81 }
82 gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu );
83
84 PostCreation();
85
86 SetBackgroundColour( parent->GetBackgroundColour() );
87
88 Show( TRUE );
89
90 return TRUE;
91 }
92
93 void wxChoice::Append( const wxString &item )
94 {
95 wxCHECK_RET( m_widget != NULL, "invalid choice" );
96
97 GtkWidget *menu = gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) );
98 GtkWidget *menu_item = gtk_menu_item_new_with_label( item );
99
100 gtk_menu_append( GTK_MENU(menu), menu_item );
101
102 gtk_widget_realize( menu_item );
103 gtk_widget_realize( GTK_BIN(menu_item)->child );
104
105 if (m_widgetStyle)
106 {
107 gtk_widget_set_style( menu_item, m_widgetStyle );
108 gtk_widget_set_style( GTK_BIN(menu_item)->child, m_widgetStyle );
109 }
110
111 gtk_signal_connect( GTK_OBJECT( menu_item ), "activate",
112 GTK_SIGNAL_FUNC(gtk_choice_clicked_callback), (gpointer*)this );
113
114 gtk_widget_show( menu_item );
115 }
116
117 void wxChoice::Clear(void)
118 {
119 wxCHECK_RET( m_widget != NULL, "invalid choice" );
120
121 gtk_option_menu_remove_menu( GTK_OPTION_MENU(m_widget) );
122 GtkWidget *menu = gtk_menu_new();
123 gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu );
124 }
125
126 void wxChoice::Delete( int WXUNUSED(n) )
127 {
128 wxFAIL_MSG( "wxChoice:Delete not implemented" );
129 }
130
131 int wxChoice::FindString( const wxString &string ) const
132 {
133 wxCHECK_MSG( m_widget != NULL, -1, "invalid choice" );
134
135 // If you read this code once and you think you understand
136 // it, then you are very wrong. Robert Roebling.
137
138 GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
139 int count = 0;
140 GList *child = menu_shell->children;
141 while (child)
142 {
143 GtkBin *bin = GTK_BIN( child->data );
144 GtkLabel *label = (GtkLabel *) NULL;
145 if (bin->child) label = GTK_LABEL(bin->child);
146 if (!label) label = GTK_LABEL( GTK_BUTTON(m_widget)->child );
147
148 wxASSERT_MSG( label != NULL , "wxChoice: invalid label" );
149
150 if (string == label->label) return count;
151 child = child->next;
152 count++;
153 }
154
155 wxFAIL_MSG( "wxChoice: string not found" );
156
157 return -1;
158 }
159
160 int wxChoice::GetColumns(void) const
161 {
162 return 1;
163 }
164
165 int wxChoice::GetSelection(void)
166 {
167 wxCHECK_MSG( m_widget != NULL, -1, "invalid choice" );
168
169 GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
170 int count = 0;
171 GList *child = menu_shell->children;
172 while (child)
173 {
174 GtkBin *bin = GTK_BIN( child->data );
175 if (!bin->child) return count;
176 child = child->next;
177 count++;
178 }
179
180 wxFAIL_MSG( "wxChoice: no selection" );
181
182 return -1;
183 }
184
185 wxString wxChoice::GetString( int n ) const
186 {
187 wxCHECK_MSG( m_widget != NULL, "", "invalid choice" );
188
189 GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
190 int count = 0;
191 GList *child = menu_shell->children;
192 while (child)
193 {
194 GtkBin *bin = GTK_BIN( child->data );
195 if (count == n)
196 {
197 GtkLabel *label = (GtkLabel *) NULL;
198 if (bin->child) label = GTK_LABEL(bin->child);
199 if (!label) label = GTK_LABEL( GTK_BUTTON(m_widget)->child );
200
201 wxASSERT_MSG( label != NULL , "wxChoice: invalid label" );
202
203 return label->label;
204 }
205 child = child->next;
206 count++;
207 }
208
209 wxFAIL_MSG( "wxChoice: string not found" );
210
211 return "";
212 }
213
214 wxString wxChoice::GetStringSelection(void) const
215 {
216 wxCHECK_MSG( m_widget != NULL, "", "invalid choice" );
217
218 GtkLabel *label = GTK_LABEL( GTK_BUTTON(m_widget)->child );
219
220 wxASSERT_MSG( label != NULL , "wxChoice: invalid label" );
221
222 return label->label;
223 }
224
225 int wxChoice::Number(void) const
226 {
227 wxCHECK_MSG( m_widget != NULL, 0, "invalid choice" );
228
229 GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
230 int count = 0;
231 GList *child = menu_shell->children;
232 while (child)
233 {
234 count++;
235 child = child->next;
236 }
237 return count;
238 }
239
240 void wxChoice::SetColumns( int WXUNUSED(n) )
241 {
242 }
243
244 void wxChoice::SetSelection( int n )
245 {
246 wxCHECK_RET( m_widget != NULL, "invalid choice" );
247
248 int tmp = n;
249 gtk_option_menu_set_history( GTK_OPTION_MENU(m_widget), (gint)tmp );
250
251 gtk_choice_clicked_callback( (GtkWidget *) NULL, this );
252 }
253
254 void wxChoice::SetStringSelection( const wxString &string )
255 {
256 wxCHECK_RET( m_widget != NULL, "invalid choice" );
257
258 int n = FindString( string );
259 if (n != -1) SetSelection( n );
260 }
261
262 void wxChoice::SetFont( const wxFont &font )
263 {
264 wxCHECK_RET( m_widget != NULL, "invalid choice" );
265
266 wxControl::SetFont( font );
267
268 GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
269 GList *child = menu_shell->children;
270 while (child)
271 {
272 GtkBin *bin = GTK_BIN( child->data );
273 GtkWidget *label = (GtkWidget *) NULL;
274 if (bin->child) label = bin->child;
275 if (!label) label = GTK_BUTTON(m_widget)->child;
276
277 gtk_widget_set_style( label, GetWidgetStyle() );
278
279 child = child->next;
280 }
281 }
282
283 void wxChoice::SetBackgroundColour( const wxColour &colour )
284 {
285 wxCHECK_RET( m_widget != NULL, "invalid choice" );
286
287 wxControl::SetBackgroundColour( colour );
288
289 if (!m_backgroundColour.Ok()) return;
290
291 GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
292
293 gtk_widget_set_style( m_widget, m_widgetStyle );
294 gtk_widget_set_style( GTK_WIDGET( menu_shell ), m_widgetStyle );
295
296 GList *child = menu_shell->children;
297 while (child)
298 {
299 gtk_widget_set_style( GTK_WIDGET( child->data ), m_widgetStyle );
300 child = child->next;
301 }
302 }
303
304
305