1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/gtk/infobar.cpp 
   3 // Purpose:     wxInfoBar implementation for GTK 
   4 // Author:      Vadim Zeitlin 
   7 // Copyright:   (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org> 
   8 // Licence:     wxWindows licence 
   9 /////////////////////////////////////////////////////////////////////////////// 
  11 // ============================================================================ 
  13 // ============================================================================ 
  15 // ---------------------------------------------------------------------------- 
  17 // ---------------------------------------------------------------------------- 
  19 // for compilers that support precompilation, includes "wx.h". 
  20 #include "wx/wxprec.h" 
  26 #include "wx/infobar.h" 
  28 #if wxUSE_INFOBAR && defined(wxHAS_NATIVE_INFOBAR) 
  33 #include "wx/vector.h" 
  34 #include "wx/stockitem.h" 
  36 #include "wx/gtk/private.h" 
  37 #include "wx/gtk/private/messagetype.h" 
  39 // ---------------------------------------------------------------------------- 
  41 // ---------------------------------------------------------------------------- 
  43 class wxInfoBarGTKImpl
 
  52     // label for the text shown in the bar 
  55     // the default close button, NULL if not needed (m_buttons is not empty) or 
  59     // information about the buttons added using AddButton() 
  62         Button(GtkWidget 
*button_
, int id_
) 
  71     typedef wxVector
<Button
> Buttons
; 
  76 // ---------------------------------------------------------------------------- 
  78 // ---------------------------------------------------------------------------- 
  83 inline bool UseNative() 
  85     // native GtkInfoBar widget is only available in GTK+ 2.18 and later 
  86     return gtk_check_version(2, 18, 0) == 0; 
  89 } // anonymous namespace 
  94 static void wxgtk_infobar_response(GtkInfoBar 
* WXUNUSED(infobar
), 
  98     win
->GTKResponse(btnid
); 
 101 static void wxgtk_infobar_close(GtkInfoBar 
* WXUNUSED(infobar
), 
 104     win
->GTKResponse(wxID_CANCEL
); 
 107 } // extern "C" section with GTK+ callbacks 
 109 // ============================================================================ 
 110 // wxInfoBar implementation 
 111 // ============================================================================ 
 113 bool wxInfoBar::Create(wxWindow 
*parent
, wxWindowID winid
) 
 116         return wxInfoBarGeneric::Create(parent
, winid
); 
 118     m_impl 
= new wxInfoBarGTKImpl
; 
 120     // this control is created initially hidden 
 122     if ( !CreateBase(parent
, winid
) ) 
 125     // create the info bar widget itself 
 126     m_widget 
= gtk_info_bar_new(); 
 127     wxCHECK_MSG( m_widget
, false, "failed to create GtkInfoBar" ); 
 128     g_object_ref(m_widget
); 
 130     // also create a label which will be used to show our message 
 131     m_impl
->m_label 
= gtk_label_new(""); 
 132     gtk_widget_show(m_impl
->m_label
); 
 135         contentArea 
= gtk_info_bar_get_content_area(GTK_INFO_BAR(m_widget
)); 
 136     wxCHECK_MSG( contentArea
, false, "failed to get GtkInfoBar content area" ); 
 137     gtk_container_add(GTK_CONTAINER(contentArea
), m_impl
->m_label
); 
 139     // finish creation and connect to all the signals we're interested in 
 140     m_parent
->DoAddChild(this); 
 142     PostCreation(wxDefaultSize
); 
 144     GTKConnectWidget("response", G_CALLBACK(wxgtk_infobar_response
)); 
 145     GTKConnectWidget("close", G_CALLBACK(wxgtk_infobar_close
)); 
 150 wxInfoBar::~wxInfoBar() 
 155 void wxInfoBar::ShowMessage(const wxString
& msg
, int flags
) 
 159         wxInfoBarGeneric::ShowMessage(msg
, flags
); 
 163     // if we don't have any buttons, create a standard close one to give the 
 164     // user at least some way to close the bar 
 165     if ( m_impl
->m_buttons
.empty() && !m_impl
->m_close 
) 
 167         m_impl
->m_close 
= GTKAddButton(wxID_CLOSE
); 
 171     if ( wxGTKImpl::ConvertMessageTypeFromWX(flags
, &type
) ) 
 172         gtk_info_bar_set_message_type(GTK_INFO_BAR(m_widget
), type
); 
 173     gtk_label_set_text(GTK_LABEL(m_impl
->m_label
), wxGTK_CONV(msg
)); 
 181 void wxInfoBar::Dismiss() 
 185         wxInfoBarGeneric::Dismiss(); 
 194 void wxInfoBar::GTKResponse(int btnid
) 
 196     wxCommandEvent 
event(wxEVT_COMMAND_BUTTON_CLICKED
, btnid
); 
 197     event
.SetEventObject(this); 
 199     if ( !HandleWindowEvent(event
) ) 
 203 GtkWidget 
*wxInfoBar::GTKAddButton(wxWindowID btnid
, const wxString
& label
) 
 205     // as GTK+ lays out the buttons vertically, adding another button changes 
 206     // our best size (at least in vertical direction) 
 207     InvalidateBestSize(); 
 209     GtkWidget 
*button 
= gtk_info_bar_add_button
 
 211                             GTK_INFO_BAR(m_widget
), 
 213                                 ? GTKConvertMnemonics(wxGetStockGtkID(btnid
)) 
 218     wxASSERT_MSG( button
, "unexpectedly failed to add button to info bar" ); 
 223 void wxInfoBar::AddButton(wxWindowID btnid
, const wxString
& label
) 
 227         wxInfoBarGeneric::AddButton(btnid
, label
); 
 231     // if we had created the default close button before, remove it now that we 
 232     // have some user-defined button 
 233     if ( m_impl
->m_close 
) 
 235         gtk_widget_destroy(m_impl
->m_close
); 
 236         m_impl
->m_close 
= NULL
; 
 239     GtkWidget 
* const button 
= GTKAddButton(btnid
, label
); 
 241         m_impl
->m_buttons
.push_back(wxInfoBarGTKImpl::Button(button
, btnid
)); 
 244 void wxInfoBar::RemoveButton(wxWindowID btnid
) 
 248         wxInfoBarGeneric::RemoveButton(btnid
); 
 252     // as in the generic version, look for the button starting from the end 
 253     wxInfoBarGTKImpl::Buttons
& buttons 
= m_impl
->m_buttons
; 
 254     for ( wxInfoBarGTKImpl::Buttons::reverse_iterator i 
= buttons
.rbegin(); 
 260             gtk_widget_destroy(i
->button
); 
 261             buttons
.erase(i
.base()); 
 263             // see comment in GTKAddButton() 
 264             InvalidateBestSize(); 
 270     wxFAIL_MSG( wxString::Format("button with id %d not found", btnid
) ); 
 273 void wxInfoBar::DoApplyWidgetStyle(GtkRcStyle 
*style
) 
 275     wxInfoBarGeneric::DoApplyWidgetStyle(style
); 
 278         gtk_widget_modify_style(m_impl
->m_label
, style
); 
 281 #endif // wxUSE_INFOBAR