~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to src/gtk/infobar.cpp

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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: infobar.cpp 71894 2012-06-30 20:39:06Z PC $
 
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
#include "wx/stockitem.h"
 
35
 
 
36
#include "wx/gtk/private.h"
 
37
#include "wx/gtk/private/messagetype.h"
 
38
 
 
39
// ----------------------------------------------------------------------------
 
40
// local classes
 
41
// ----------------------------------------------------------------------------
 
42
 
 
43
class wxInfoBarGTKImpl
 
44
{
 
45
public:
 
46
    wxInfoBarGTKImpl()
 
47
    {
 
48
        m_label = NULL;
 
49
        m_close = NULL;
 
50
    }
 
51
 
 
52
    // label for the text shown in the bar
 
53
    GtkWidget *m_label;
 
54
 
 
55
    // the default close button, NULL if not needed (m_buttons is not empty) or
 
56
    // not created yet
 
57
    GtkWidget *m_close;
 
58
 
 
59
    // information about the buttons added using AddButton()
 
60
    struct Button
 
61
    {
 
62
        Button(GtkWidget *button_, int id_)
 
63
            : button(button_),
 
64
              id(id_)
 
65
        {
 
66
        }
 
67
 
 
68
        GtkWidget *button;
 
69
        int id;
 
70
    };
 
71
    typedef wxVector<Button> Buttons;
 
72
 
 
73
    Buttons m_buttons;
 
74
};
 
75
 
 
76
// ----------------------------------------------------------------------------
 
77
// local functions
 
78
// ----------------------------------------------------------------------------
 
79
 
 
80
namespace
 
81
{
 
82
 
 
83
inline bool UseNative()
 
84
{
 
85
#ifdef __WXGTK3__
 
86
    return true;
 
87
#else
 
88
    // native GtkInfoBar widget is only available in GTK+ 2.18 and later
 
89
    return gtk_check_version(2, 18, 0) == 0;
 
90
#endif
 
91
}
 
92
 
 
93
} // anonymous namespace
 
94
 
 
95
extern "C"
 
96
{
 
97
 
 
98
static void wxgtk_infobar_response(GtkInfoBar * WXUNUSED(infobar),
 
99
                                   gint btnid,
 
100
                                   wxInfoBar *win)
 
101
{
 
102
    win->GTKResponse(btnid);
 
103
}
 
104
 
 
105
static void wxgtk_infobar_close(GtkInfoBar * WXUNUSED(infobar),
 
106
                                wxInfoBar *win)
 
107
{
 
108
    win->GTKResponse(wxID_CANCEL);
 
109
}
 
110
 
 
111
} // extern "C" section with GTK+ callbacks
 
112
 
 
113
// ============================================================================
 
114
// wxInfoBar implementation
 
115
// ============================================================================
 
116
 
 
117
bool wxInfoBar::Create(wxWindow *parent, wxWindowID winid)
 
118
{
 
119
    if ( !UseNative() )
 
120
        return wxInfoBarGeneric::Create(parent, winid);
 
121
 
 
122
    m_impl = new wxInfoBarGTKImpl;
 
123
 
 
124
    // this control is created initially hidden
 
125
    Hide();
 
126
    if ( !CreateBase(parent, winid) )
 
127
        return false;
 
128
 
 
129
    // create the info bar widget itself
 
130
    m_widget = gtk_info_bar_new();
 
131
    wxCHECK_MSG( m_widget, false, "failed to create GtkInfoBar" );
 
132
    g_object_ref(m_widget);
 
133
 
 
134
    // also create a label which will be used to show our message
 
135
    m_impl->m_label = gtk_label_new("");
 
136
    gtk_widget_show(m_impl->m_label);
 
137
 
 
138
    GtkWidget * const
 
139
        contentArea = gtk_info_bar_get_content_area(GTK_INFO_BAR(m_widget));
 
140
    wxCHECK_MSG( contentArea, false, "failed to get GtkInfoBar content area" );
 
141
    gtk_container_add(GTK_CONTAINER(contentArea), m_impl->m_label);
 
142
 
 
143
    // finish creation and connect to all the signals we're interested in
 
144
    m_parent->DoAddChild(this);
 
145
 
 
146
    PostCreation(wxDefaultSize);
 
147
 
 
148
    GTKConnectWidget("response", G_CALLBACK(wxgtk_infobar_response));
 
149
    GTKConnectWidget("close", G_CALLBACK(wxgtk_infobar_close));
 
150
 
 
151
    return true;
 
152
}
 
153
 
 
154
wxInfoBar::~wxInfoBar()
 
155
{
 
156
    delete m_impl;
 
157
}
 
158
 
 
159
void wxInfoBar::ShowMessage(const wxString& msg, int flags)
 
160
{
 
161
    if ( !UseNative() )
 
162
    {
 
163
        wxInfoBarGeneric::ShowMessage(msg, flags);
 
164
        return;
 
165
    }
 
166
 
 
167
    // if we don't have any buttons, create a standard close one to give the
 
168
    // user at least some way to close the bar
 
169
    if ( m_impl->m_buttons.empty() && !m_impl->m_close )
 
170
    {
 
171
        m_impl->m_close = GTKAddButton(wxID_CLOSE);
 
172
    }
 
173
 
 
174
    GtkMessageType type;
 
175
    if ( wxGTKImpl::ConvertMessageTypeFromWX(flags, &type) )
 
176
        gtk_info_bar_set_message_type(GTK_INFO_BAR(m_widget), type);
 
177
    gtk_label_set_text(GTK_LABEL(m_impl->m_label), wxGTK_CONV(msg));
 
178
 
 
179
    if ( !IsShown() )
 
180
        Show();
 
181
 
 
182
    UpdateParent();
 
183
}
 
184
 
 
185
void wxInfoBar::Dismiss()
 
186
{
 
187
    if ( !UseNative() )
 
188
    {
 
189
        wxInfoBarGeneric::Dismiss();
 
190
        return;
 
191
    }
 
192
 
 
193
    Hide();
 
194
 
 
195
    UpdateParent();
 
196
}
 
197
 
 
198
void wxInfoBar::GTKResponse(int btnid)
 
199
{
 
200
    wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, btnid);
 
201
    event.SetEventObject(this);
 
202
 
 
203
    if ( !HandleWindowEvent(event) )
 
204
        Dismiss();
 
205
}
 
206
 
 
207
GtkWidget *wxInfoBar::GTKAddButton(wxWindowID btnid, const wxString& label)
 
208
{
 
209
    // as GTK+ lays out the buttons vertically, adding another button changes
 
210
    // our best size (at least in vertical direction)
 
211
    InvalidateBestSize();
 
212
 
 
213
    GtkWidget *button = gtk_info_bar_add_button
 
214
                        (
 
215
                            GTK_INFO_BAR(m_widget),
 
216
                            (label.empty()
 
217
                                ? GTKConvertMnemonics(wxGetStockGtkID(btnid))
 
218
                                : label).utf8_str(),
 
219
                            btnid
 
220
                        );
 
221
 
 
222
    wxASSERT_MSG( button, "unexpectedly failed to add button to info bar" );
 
223
 
 
224
    return button;
 
225
}
 
226
 
 
227
void wxInfoBar::AddButton(wxWindowID btnid, const wxString& label)
 
228
{
 
229
    if ( !UseNative() )
 
230
    {
 
231
        wxInfoBarGeneric::AddButton(btnid, label);
 
232
        return;
 
233
    }
 
234
 
 
235
    // if we had created the default close button before, remove it now that we
 
236
    // have some user-defined button
 
237
    if ( m_impl->m_close )
 
238
    {
 
239
        gtk_widget_destroy(m_impl->m_close);
 
240
        m_impl->m_close = NULL;
 
241
    }
 
242
 
 
243
    GtkWidget * const button = GTKAddButton(btnid, label);
 
244
    if ( button )
 
245
        m_impl->m_buttons.push_back(wxInfoBarGTKImpl::Button(button, btnid));
 
246
}
 
247
 
 
248
void wxInfoBar::RemoveButton(wxWindowID btnid)
 
249
{
 
250
    if ( !UseNative() )
 
251
    {
 
252
        wxInfoBarGeneric::RemoveButton(btnid);
 
253
        return;
 
254
    }
 
255
 
 
256
    // as in the generic version, look for the button starting from the end
 
257
    wxInfoBarGTKImpl::Buttons& buttons = m_impl->m_buttons;
 
258
    for ( wxInfoBarGTKImpl::Buttons::reverse_iterator i = buttons.rbegin();
 
259
          i != buttons.rend();
 
260
          ++i )
 
261
    {
 
262
        if (i->id == btnid)
 
263
        {
 
264
            gtk_widget_destroy(i->button);
 
265
            buttons.erase(i.base());
 
266
 
 
267
            // see comment in GTKAddButton()
 
268
            InvalidateBestSize();
 
269
 
 
270
            return;
 
271
        }
 
272
    }
 
273
 
 
274
    wxFAIL_MSG( wxString::Format("button with id %d not found", btnid) );
 
275
}
 
276
 
 
277
void wxInfoBar::DoApplyWidgetStyle(GtkRcStyle *style)
 
278
{
 
279
    wxInfoBarGeneric::DoApplyWidgetStyle(style);
 
280
 
 
281
    if ( UseNative() )
 
282
        GTKApplyStyle(m_impl->m_label, style);
 
283
}
 
284
 
 
285
#endif // wxUSE_INFOBAR