1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/infobar.cpp
3 // Purpose: generic wxInfoBar implementation
4 // Author: Vadim Zeitlin
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 ///////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // for compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
29 #include "wx/artprov.h"
30 #include "wx/bmpbuttn.h"
31 #include "wx/button.h"
32 #include "wx/settings.h"
33 #include "wx/statbmp.h"
34 #include "wx/stattext.h"
37 #include "wx/infobar.h"
39 #include "wx/scopeguard.h"
42 // ============================================================================
44 // ============================================================================
46 void wxInfoBar::Init()
52 m_showEffect
= wxSHOW_EFFECT_SLIDE_TO_BOTTOM
;
53 m_hideEffect
= wxSHOW_EFFECT_SLIDE_TO_TOP
;
55 // use default effect duration
59 bool wxInfoBar::Create(wxWindow
*parent
, wxWindowID winid
)
61 // calling Hide() before Create() ensures that we're created initially
64 if ( !wxWindow::Create(parent
, winid
) )
67 // use special, easy to notice, colours
68 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOBK
));
69 SetOwnForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOTEXT
));
71 // create the controls: icon, text and the button to dismiss the
74 // the icon is not shown unless it's assigned a valid bitmap
75 m_icon
= new wxStaticBitmap(this, wxID_ANY
, wxNullBitmap
);
77 // by default, the text uses a larger, more noticeable, font
78 m_text
= new wxStaticText(this, wxID_ANY
, "");
79 m_text
->SetFont(m_text
->GetFont().Bold().Larger());
81 m_button
= new wxBitmapButton
85 wxArtProvider::GetBitmap(wxART_CROSS_MARK
),
90 m_button
->SetToolTip(_("Hide this notification message."));
94 wxEVT_COMMAND_BUTTON_CLICKED
,
95 wxCommandEventHandler(wxInfoBar::OnButton
),
100 // center the text inside the sizer with an icon to the left of it and a
101 // button at the very right
103 // NB: AddButton() relies on the button being the last control in the sizer
104 // and being preceded by a spacer
105 wxSizer
* const sizer
= new wxBoxSizer(wxHORIZONTAL
);
106 sizer
->AddStretchSpacer();
107 sizer
->Add(m_icon
, wxSizerFlags().Centre().DoubleBorder());
108 sizer
->Add(m_text
, wxSizerFlags().Centre().DoubleBorder());
109 sizer
->AddStretchSpacer();
110 sizer
->Add(m_button
, wxSizerFlags().Centre().DoubleBorder());
116 bool wxInfoBar::SetFont(const wxFont
& font
)
118 if ( !wxInfoBarBase::SetFont(font
) )
121 // check that we're not called before Create()
123 m_text
->SetFont(font
);
128 void wxInfoBar::UpdateParent()
130 wxWindow
* const parent
= wxGetTopLevelParent(GetParent());
134 void wxInfoBar::ChangeParentBackground()
136 wxWindow
* const parent
= GetParent();
137 m_origParentBgCol
= parent
->GetBackgroundColour();
139 wxSizer
* const sizer
= GetContainingSizer();
143 wxWindow
*sibling
= NULL
;
144 for ( wxSizerItemList::compatibility_iterator
145 node
= sizer
->GetChildren().GetFirst();
147 node
= node
->GetNext() )
149 if ( node
->GetData()->GetWindow() == this )
151 // find the next window following us
152 for ( node
= node
->GetNext();
154 node
= node
->GetNext() )
156 wxSizerItem
* const item
= node
->GetData();
157 if ( item
->IsWindow() )
159 sibling
= item
->GetWindow();
169 parent
->SetOwnBackgroundColour(sibling
->GetBackgroundColour());
172 void wxInfoBar::RestoreParentBackground()
174 GetParent()->SetOwnBackgroundColour(m_origParentBgCol
);
177 void wxInfoBar::DoHide()
179 ChangeParentBackground();
180 wxON_BLOCK_EXIT_THIS0( wxInfoBar::RestoreParentBackground
);
182 HideWithEffect(m_hideEffect
, m_effectDuration
);
186 void wxInfoBar::DoShow()
188 // re-layout the parent first so that the window expands into an already
189 // unoccupied by the other controls area: for this we need to change our
190 // internal visibility flag to force Layout() to take us into account (an
191 // alternative solution to this hack would be to temporarily set
192 // wxRESERVE_SPACE_EVEN_IF_HIDDEN flag but it's not really batter)
194 // just change the internal flag indicating that the window is visible,
195 // without really showing it
196 wxWindowBase::Show();
198 // an extra hack: we want the temporarily uncovered area in which we're
199 // going to expand to look like part of this sibling for a better effect so
200 // temporarily change the background of our parent to the same colour
201 ChangeParentBackground();
202 wxON_BLOCK_EXIT_THIS0( wxInfoBar::RestoreParentBackground
);
204 // adjust the parent layout to account for us
207 // reset the flag back before really showing the window or it wouldn't be
208 // shown at all because it would believe itself already visible
209 wxWindowBase::Show(false);
212 // finally do really show the window.
213 ShowWithEffect(m_showEffect
, m_effectDuration
);
216 void wxInfoBar::ShowMessage(const wxString
& msg
, int flags
)
218 // first update the controls
219 const int icon
= flags
& wxICON_MASK
;
220 if ( !icon
|| (icon
== wxICON_NONE
) )
224 else // do show an icon
226 m_icon
->SetBitmap(wxArtProvider::GetMessageBoxIcon(icon
));
230 // notice the use of EscapeMnemonics() to ensure that "&" come through
232 m_text
->SetLabel(wxControl::EscapeMnemonics(msg
));
235 // then show this entire window if not done yet
240 else // we're already shown
242 // just update the layout to correspond to the new message
247 void wxInfoBar::AddButton(wxWindowID btnid
, const wxString
& label
)
249 wxSizer
* const sizer
= GetSizer();
250 wxCHECK_RET( sizer
, "must be created first" );
252 sizer
->Insert(sizer
->GetItemCount() - 2,
253 new wxButton(this, btnid
, label
),
254 wxSizerFlags().Centre().DoubleBorder());
257 void wxInfoBar::OnButton(wxCommandEvent
& WXUNUSED(event
))
262 #endif // wxUSE_INFOBAR