Add wxInfoBar::RemoveButton() method.
[wxWidgets.git] / src / gtk / infobar.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/infobar.cpp
3 // Purpose: wxInfoBar implementation for GTK
4 // Author: Vadim Zeitlin
5 // Created: 2009-09-27
6 // RCS-ID: $Id: wxhead.cpp,v 1.10 2009-06-29 10:23:04 zeitlin Exp $
7 // Copyright: (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // for compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #include "wx/infobar.h"
27
28 #if wxUSE_INFOBAR && defined(wxHAS_NATIVE_INFOBAR)
29
30 #ifndef WX_PRECOMP
31 #endif // WX_PRECOMP
32
33 #include "wx/vector.h"
34
35 #include "wx/gtk/private.h"
36 #include "wx/gtk/private/messagetype.h"
37
38 // ----------------------------------------------------------------------------
39 // local classes
40 // ----------------------------------------------------------------------------
41
42 class wxInfoBarGTKImpl
43 {
44 public:
45 wxInfoBarGTKImpl()
46 {
47 m_label = NULL;
48 }
49
50 GtkWidget *m_label;
51
52 struct Button
53 {
54 Button(GtkWidget *button_, int id_)
55 : button(button_),
56 id(id_)
57 {
58 }
59
60 GtkWidget *button;
61 int id;
62 };
63 typedef wxVector<Button> Buttons;
64
65 Buttons m_buttons;
66 };
67
68 // ----------------------------------------------------------------------------
69 // local functions
70 // ----------------------------------------------------------------------------
71
72 namespace
73 {
74
75 inline bool UseNative()
76 {
77 // native GtkInfoBar widget is only available in GTK+ 2.18 and later
78 return gtk_check_version(2, 18, 0) == 0;
79 }
80
81 } // anonymous namespace
82
83 extern "C"
84 {
85
86 static void wxgtk_infobar_response(GtkInfoBar * WXUNUSED(infobar),
87 gint btnid,
88 wxInfoBar *win)
89 {
90 win->GTKResponse(btnid);
91 }
92
93 static void wxgtk_infobar_close(GtkInfoBar * WXUNUSED(infobar),
94 wxInfoBar *win)
95 {
96 win->GTKResponse(wxID_CANCEL);
97 }
98
99 } // extern "C" section with GTK+ callbacks
100
101 // ============================================================================
102 // wxInfoBar implementation
103 // ============================================================================
104
105 bool wxInfoBar::Create(wxWindow *parent, wxWindowID winid)
106 {
107 if ( !UseNative() )
108 return wxInfoBarGeneric::Create(parent, winid);
109
110 m_impl = new wxInfoBarGTKImpl;
111
112 // this control is created initially hidden
113 Hide();
114 if ( !CreateBase(parent, winid) )
115 return false;
116
117 // create the info bar widget itself
118 m_widget = gtk_info_bar_new();
119 wxCHECK_MSG( m_widget, false, "failed to create GtkInfoBar" );
120 g_object_ref(m_widget);
121
122 // also create a label which will be used to show our message
123 m_impl->m_label = gtk_label_new("");
124 gtk_widget_show(m_impl->m_label);
125
126 GtkWidget * const
127 contentArea = gtk_info_bar_get_content_area(GTK_INFO_BAR(m_widget));
128 wxCHECK_MSG( contentArea, false, "failed to get GtkInfoBar content area" );
129 gtk_container_add(GTK_CONTAINER(contentArea), m_impl->m_label);
130
131 // finish creation and connect to all the signals we're interested in
132 m_parent->DoAddChild(this);
133
134 PostCreation(wxDefaultSize);
135
136 GTKConnectWidget("response", G_CALLBACK(wxgtk_infobar_response));
137 GTKConnectWidget("close", G_CALLBACK(wxgtk_infobar_close));
138
139 return false;
140 }
141
142 wxInfoBar::~wxInfoBar()
143 {
144 delete m_impl;
145 }
146
147 void wxInfoBar::ShowMessage(const wxString& msg, int flags)
148 {
149 if ( !UseNative() )
150 {
151 wxInfoBarGeneric::ShowMessage(msg, flags);
152 return;
153 }
154
155 GtkMessageType type;
156 if ( wxGTKImpl::ConvertMessageTypeFromWX(flags, &type) )
157 gtk_info_bar_set_message_type(GTK_INFO_BAR(m_widget), type);
158 gtk_label_set_text(GTK_LABEL(m_impl->m_label), wxGTK_CONV(msg));
159
160 if ( !IsShown() )
161 Show();
162
163 UpdateParent();
164 }
165
166 void wxInfoBar::GTKResponse(int WXUNUSED(btnid))
167 {
168 Hide();
169
170 UpdateParent();
171 }
172
173 void wxInfoBar::AddButton(wxWindowID btnid, const wxString& label)
174 {
175 if ( !UseNative() )
176 {
177 wxInfoBarGeneric::AddButton(btnid, label);
178 return;
179 }
180
181 GtkWidget *button = gtk_info_bar_add_button
182 (
183 GTK_INFO_BAR(m_widget),
184 label.empty()
185 ? GTKConvertMnemonics(wxGetStockGtkID(btnid))
186 : label,
187 btnid
188 );
189 wxCHECK_RET( button, "unexpectedly failed to add button to info bar" );
190
191 g_object_ref(button);
192 m_impl->m_buttons.push_back(wxInfoBarGTKImpl::Button(button, btnid));
193 }
194
195 void wxInfoBar::RemoveButton(wxWindowID btnid)
196 {
197 if ( !UseNative() )
198 {
199 wxInfoBarGeneric::RemoveButton(btnid);
200 return;
201 }
202
203 // as in the generic version, look for the button starting from the end
204 wxInfoBarGTKImpl::Buttons& buttons = m_impl->m_buttons;
205 for ( wxInfoBarGTKImpl::Buttons::reverse_iterator i = buttons.rbegin();
206 i != buttons.rend();
207 ++i )
208 {
209 GtkWidget * const button = i->button;
210 buttons.erase(i.base());
211 gtk_widget_destroy(button);
212 g_object_unref(button);
213 return;
214 }
215
216 wxFAIL_MSG( wxString::Format("button with id %d not found", btnid) );
217 }
218
219 #endif // wxUSE_INFOBAR