1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
12 #pragma implementation "choice.h"
15 #include "wx/choice.h"
17 //-----------------------------------------------------------------------------
19 //-----------------------------------------------------------------------------
21 extern bool g_blockEventsOnDrag
;
23 //-----------------------------------------------------------------------------
25 //-----------------------------------------------------------------------------
27 static void gtk_choice_clicked_callback( GtkWidget
*WXUNUSED(widget
), wxChoice
*choice
)
29 if (!choice
->HasVMT()) return;
30 if (g_blockEventsOnDrag
) return;
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
);
40 //-----------------------------------------------------------------------------
42 //-----------------------------------------------------------------------------
44 IMPLEMENT_DYNAMIC_CLASS(wxChoice
,wxControl
)
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
)
57 PreCreation( parent
, id
, pos
, size
, style
, name
);
59 SetValidator( validator
);
61 m_widget
= gtk_option_menu_new();
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
);
68 GtkWidget
*menu
= gtk_menu_new();
70 for (int i
= 0; i
< n
; i
++)
72 m_clientDataList
.Append( (wxObject
*) NULL
);
73 m_clientObjectList
.Append( (wxObject
*) NULL
);
75 GtkWidget
*item
= gtk_menu_item_new_with_label( choices
[i
] );
76 gtk_menu_append( GTK_MENU(menu
), item
);
78 gtk_widget_realize( item
);
79 gtk_widget_realize( GTK_BIN(item
)->child
);
81 gtk_widget_show( item
);
83 gtk_signal_connect( GTK_OBJECT( item
), "activate",
84 GTK_SIGNAL_FUNC(gtk_choice_clicked_callback
), (gpointer
*)this );
86 gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget
), menu
);
88 m_parent
->AddChild( this );
90 (m_parent
->m_insertCallback
)( m_parent
, this );
94 SetBackgroundColour( parent
->GetBackgroundColour() );
95 SetForegroundColour( parent
->GetForegroundColour() );
102 wxChoice::~wxChoice()
107 void wxChoice::AppendCommon( const wxString
&item
)
109 wxCHECK_RET( m_widget
!= NULL
, "invalid choice" );
111 GtkWidget
*menu
= gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget
) );
112 GtkWidget
*menu_item
= gtk_menu_item_new_with_label( item
);
114 gtk_menu_append( GTK_MENU(menu
), menu_item
);
116 gtk_widget_realize( menu_item
);
117 gtk_widget_realize( GTK_BIN(menu_item
)->child
);
119 if (m_widgetStyle
) ApplyWidgetStyle();
121 gtk_signal_connect( GTK_OBJECT( menu_item
), "activate",
122 GTK_SIGNAL_FUNC(gtk_choice_clicked_callback
), (gpointer
*)this );
124 gtk_widget_show( menu_item
);
127 void wxChoice::Append( const wxString
&item
)
129 m_clientDataList
.Append( (wxObject
*) NULL
);
130 m_clientObjectList
.Append( (wxObject
*) NULL
);
132 AppendCommon( item
);
135 void wxChoice::Append( const wxString
&item
, void *clientData
)
137 m_clientDataList
.Append( (wxObject
*) clientData
);
138 m_clientObjectList
.Append( (wxObject
*) NULL
);
140 AppendCommon( item
);
143 void wxChoice::Append( const wxString
&item
, wxClientData
*clientData
)
145 m_clientObjectList
.Append( (wxObject
*) clientData
);
146 m_clientDataList
.Append( (wxObject
*) NULL
);
148 AppendCommon( item
);
151 void wxChoice::SetClientData( int n
, void* clientData
)
153 wxCHECK_RET( m_widget
!= NULL
, "invalid combobox" );
155 wxNode
*node
= m_clientDataList
.Nth( n
);
158 node
->SetData( (wxObject
*) clientData
);
161 void* wxChoice::GetClientData( int n
)
163 wxCHECK_MSG( m_widget
!= NULL
, NULL
, "invalid combobox" );
165 wxNode
*node
= m_clientDataList
.Nth( n
);
166 if (!node
) return NULL
;
171 void wxChoice::SetClientObject( int n
, wxClientData
* clientData
)
173 wxCHECK_RET( m_widget
!= NULL
, "invalid combobox" );
175 wxNode
*node
= m_clientObjectList
.Nth( n
);
178 wxClientData
*cd
= (wxClientData
*) node
->Data();
181 node
->SetData( (wxObject
*) clientData
);
184 wxClientData
* wxChoice::GetClientObject( int n
)
186 wxCHECK_MSG( m_widget
!= NULL
, (wxClientData
*) NULL
, "invalid combobox" );
188 wxNode
*node
= m_clientObjectList
.Nth( n
);
189 if (!node
) return (wxClientData
*) NULL
;
191 return (wxClientData
*) node
->Data();
194 void wxChoice::Clear()
196 wxCHECK_RET( m_widget
!= NULL
, "invalid choice" );
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
);
202 wxNode
*node
= m_clientObjectList
.First();
205 wxClientData
*cd
= (wxClientData
*)node
->Data();
209 m_clientObjectList
.Clear();
211 m_clientDataList
.Clear();
214 void wxChoice::Delete( int WXUNUSED(n
) )
216 wxFAIL_MSG( "wxChoice:Delete not implemented" );
219 int wxChoice::FindString( const wxString
&string
) const
221 wxCHECK_MSG( m_widget
!= NULL
, -1, "invalid choice" );
223 // If you read this code once and you think you understand
224 // it, then you are very wrong. Robert Roebling.
226 GtkMenuShell
*menu_shell
= GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget
) ) );
228 GList
*child
= menu_shell
->children
;
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
);
236 wxASSERT_MSG( label
!= NULL
, "wxChoice: invalid label" );
238 if (string
== label
->label
) return count
;
243 wxFAIL_MSG( "wxChoice: string not found" );
248 int wxChoice::GetColumns() const
253 int wxChoice::GetSelection()
255 wxCHECK_MSG( m_widget
!= NULL
, -1, "invalid choice" );
257 GtkMenuShell
*menu_shell
= GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget
) ) );
259 GList
*child
= menu_shell
->children
;
262 GtkBin
*bin
= GTK_BIN( child
->data
);
263 if (!bin
->child
) return count
;
268 wxFAIL_MSG( "wxChoice: no selection" );
273 wxString
wxChoice::GetString( int n
) const
275 wxCHECK_MSG( m_widget
!= NULL
, "", "invalid choice" );
277 GtkMenuShell
*menu_shell
= GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget
) ) );
279 GList
*child
= menu_shell
->children
;
282 GtkBin
*bin
= GTK_BIN( child
->data
);
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
);
289 wxASSERT_MSG( label
!= NULL
, "wxChoice: invalid label" );
297 wxFAIL_MSG( "wxChoice: string not found" );
302 wxString
wxChoice::GetStringSelection() const
304 wxCHECK_MSG( m_widget
!= NULL
, "", "invalid choice" );
306 GtkLabel
*label
= GTK_LABEL( GTK_BUTTON(m_widget
)->child
);
308 wxASSERT_MSG( label
!= NULL
, "wxChoice: invalid label" );
313 int wxChoice::Number() const
315 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid choice" );
317 GtkMenuShell
*menu_shell
= GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget
) ) );
319 GList
*child
= menu_shell
->children
;
328 void wxChoice::SetColumns( int WXUNUSED(n
) )
332 void wxChoice::SetSelection( int n
)
334 wxCHECK_RET( m_widget
!= NULL
, "invalid choice" );
337 gtk_option_menu_set_history( GTK_OPTION_MENU(m_widget
), (gint
)tmp
);
339 gtk_choice_clicked_callback( (GtkWidget
*) NULL
, this );
342 void wxChoice::SetStringSelection( const wxString
&string
)
344 wxCHECK_RET( m_widget
!= NULL
, "invalid choice" );
346 int n
= FindString( string
);
347 if (n
!= -1) SetSelection( n
);
350 void wxChoice::ApplyWidgetStyle()
354 GtkMenuShell
*menu_shell
= GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget
) ) );
356 gtk_widget_set_style( m_widget
, m_widgetStyle
);
357 gtk_widget_set_style( GTK_WIDGET( menu_shell
), m_widgetStyle
);
359 GList
*child
= menu_shell
->children
;
362 gtk_widget_set_style( GTK_WIDGET( child
->data
), m_widgetStyle
);
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
;
369 gtk_widget_set_style( label
, m_widgetStyle
);