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/settings.h"
32 #include "wx/statbmp.h"
33 #include "wx/stattext.h"
36 #include "wx/infobar.h"
38 #include "wx/scopeguard.h"
41 // ============================================================================
43 // ============================================================================
45 void wxInfoBar::Init()
51 m_showEffect
= wxSHOW_EFFECT_SLIDE_TO_BOTTOM
;
52 m_hideEffect
= wxSHOW_EFFECT_SLIDE_TO_TOP
;
54 // use default effect duration
58 bool wxInfoBar::Create(wxWindow
*parent
, wxWindowID winid
)
60 // calling Hide() before Create() ensures that we're created initially
63 if ( !wxWindow::Create(parent
, winid
) )
66 // use special, easy to notice, colours
67 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOBK
));
68 SetOwnForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOTEXT
));
70 // create the controls: icon, text and the button to dismiss the
73 // the icon is not shown unless it's assigned a valid bitmap
74 m_icon
= new wxStaticBitmap(this, wxID_ANY
, wxNullBitmap
);
76 // by default, the text uses a larger, more noticeable, font
77 m_text
= new wxStaticText(this, wxID_ANY
, "");
78 m_text
->SetFont(m_text
->GetFont().Bold().Larger());
80 m_button
= new wxBitmapButton
84 wxArtProvider::GetBitmap(wxART_CROSS_MARK
),
89 m_button
->SetToolTip(_("Hide this notification message."));
93 wxEVT_COMMAND_BUTTON_CLICKED
,
94 wxCommandEventHandler(wxInfoBar::OnButton
),
99 // Center the text inside the sizer.
100 wxSizer
* const sizer
= new wxBoxSizer(wxHORIZONTAL
);
101 sizer
->AddStretchSpacer();
102 sizer
->Add(m_icon
, wxSizerFlags().Centre().DoubleBorder());
103 sizer
->Add(m_text
, wxSizerFlags().Centre().DoubleBorder());
104 sizer
->AddStretchSpacer();
105 sizer
->Add(m_button
, wxSizerFlags().Centre().DoubleBorder());
111 bool wxInfoBar::SetFont(const wxFont
& font
)
113 if ( !wxInfoBarBase::SetFont(font
) )
116 // check that we're not called before Create()
118 m_text
->SetFont(font
);
123 void wxInfoBar::UpdateParent()
125 wxWindow
* const parent
= wxGetTopLevelParent(GetParent());
129 void wxInfoBar::ChangeParentBackground()
131 wxWindow
* const parent
= GetParent();
132 m_origParentBgCol
= parent
->GetBackgroundColour();
134 wxSizer
* const sizer
= GetContainingSizer();
138 wxWindow
*sibling
= NULL
;
139 for ( wxSizerItemList::compatibility_iterator
140 node
= sizer
->GetChildren().GetFirst();
142 node
= node
->GetNext() )
144 if ( node
->GetData()->GetWindow() == this )
146 // find the next window following us
147 for ( node
= node
->GetNext();
149 node
= node
->GetNext() )
151 wxSizerItem
* const item
= node
->GetData();
152 if ( item
->IsWindow() )
154 sibling
= item
->GetWindow();
164 parent
->SetOwnBackgroundColour(sibling
->GetBackgroundColour());
167 void wxInfoBar::RestoreParentBackground()
169 GetParent()->SetOwnBackgroundColour(m_origParentBgCol
);
172 void wxInfoBar::DoHide()
174 ChangeParentBackground();
175 wxON_BLOCK_EXIT_THIS0( wxInfoBar::RestoreParentBackground
);
177 HideWithEffect(m_hideEffect
, m_effectDuration
);
181 void wxInfoBar::DoShow()
183 // re-layout the parent first so that the window expands into an already
184 // unoccupied by the other controls area: for this we need to change our
185 // internal visibility flag to force Layout() to take us into account (an
186 // alternative solution to this hack would be to temporarily set
187 // wxRESERVE_SPACE_EVEN_IF_HIDDEN flag but it's not really batter)
189 // just change the internal flag indicating that the window is visible,
190 // without really showing it
191 wxWindowBase::Show();
193 // an extra hack: we want the temporarily uncovered area in which we're
194 // going to expand to look like part of this sibling for a better effect so
195 // temporarily change the background of our parent to the same colour
196 ChangeParentBackground();
197 wxON_BLOCK_EXIT_THIS0( wxInfoBar::RestoreParentBackground
);
199 // adjust the parent layout to account for us
202 // reset the flag back before really showing the window or it wouldn't be
203 // shown at all because it would believe itself already visible
204 wxWindowBase::Show(false);
207 // finally do really show the window.
208 ShowWithEffect(m_showEffect
, m_effectDuration
);
211 void wxInfoBar::ShowMessage(const wxString
& msg
, int flags
)
213 // first update the controls
214 const int icon
= flags
& wxICON_MASK
;
215 if ( !icon
|| (icon
== wxICON_NONE
) )
219 else // do show an icon
221 m_icon
->SetBitmap(wxArtProvider::GetMessageBoxIcon(icon
));
225 // notice the use of EscapeMnemonics() to ensure that "&" come through
227 m_text
->SetLabel(wxControl::EscapeMnemonics(msg
));
230 // then show this entire window if not done yet
235 else // we're already shown
237 // just update the layout to correspond to the new message
242 void wxInfoBar::OnButton(wxCommandEvent
& WXUNUSED(event
))
247 #endif // wxUSE_INFOBAR