]> git.saurik.com Git - wxWidgets.git/blob - src/generic/infobar.cpp
db8708a56bc7c1430974028c0193bf3ee55dee91
[wxWidgets.git] / src / generic / infobar.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/infobar.cpp
3 // Purpose: generic wxInfoBar implementation
4 // Author: Vadim Zeitlin
5 // Created: 2009-07-28
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 #if wxUSE_INFOBAR
27
28 #ifndef WX_PRECOMP
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"
34 #endif // WX_PRECOMP
35
36 #include "wx/infobar.h"
37
38 #include "wx/scopeguard.h"
39 #include "wx/sizer.h"
40
41 // ============================================================================
42 // implementation
43 // ============================================================================
44
45 void wxInfoBar::Init()
46 {
47 m_icon = NULL;
48 m_text = NULL;
49 m_button = NULL;
50
51 m_showEffect = wxSHOW_EFFECT_SLIDE_TO_BOTTOM;
52 m_hideEffect = wxSHOW_EFFECT_SLIDE_TO_TOP;
53
54 // use default effect duration
55 m_effectDuration = 0;
56 }
57
58 bool wxInfoBar::Create(wxWindow *parent, wxWindowID winid)
59 {
60 // calling Hide() before Create() ensures that we're created initially
61 // hidden
62 Hide();
63 if ( !wxWindow::Create(parent, winid) )
64 return false;
65
66 // use special, easy to notice, colours
67 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOBK));
68 SetOwnForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOTEXT));
69
70 // create the controls: icon, text and the button to dismiss the
71 // message.
72
73 // the icon is not shown unless it's assigned a valid bitmap
74 m_icon = new wxStaticBitmap(this, wxID_ANY, wxNullBitmap);
75
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());
79
80 m_button = new wxBitmapButton
81 (
82 this,
83 wxID_ANY,
84 wxArtProvider::GetBitmap(wxART_CROSS_MARK),
85 wxDefaultPosition,
86 wxDefaultSize,
87 wxBORDER_NONE
88 );
89 m_button->SetToolTip(_("Hide this notification message."));
90
91 Connect
92 (
93 wxEVT_COMMAND_BUTTON_CLICKED,
94 wxCommandEventHandler(wxInfoBar::OnButton),
95 NULL,
96 this
97 );
98
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());
106 SetSizer(sizer);
107
108 return true;
109 }
110
111 void wxInfoBar::UpdateParent()
112 {
113 wxWindow * const parent = wxGetTopLevelParent(GetParent());
114 parent->Layout();
115 }
116
117 void wxInfoBar::ChangeParentBackground()
118 {
119 wxWindow * const parent = GetParent();
120 m_origParentBgCol = parent->GetBackgroundColour();
121
122 wxSizer * const sizer = GetContainingSizer();
123 if ( !sizer )
124 return;
125
126 wxWindow *sibling = NULL;
127 for ( wxSizerItemList::compatibility_iterator
128 node = sizer->GetChildren().GetFirst();
129 node;
130 node = node->GetNext() )
131 {
132 if ( node->GetData()->GetWindow() == this )
133 {
134 // find the next window following us
135 for ( node = node->GetNext();
136 node;
137 node = node->GetNext() )
138 {
139 wxSizerItem * const item = node->GetData();
140 if ( item->IsWindow() )
141 {
142 sibling = item->GetWindow();
143 break;
144 }
145 }
146
147 break;
148 }
149 }
150
151 if ( sibling )
152 parent->SetOwnBackgroundColour(sibling->GetBackgroundColour());
153 }
154
155 void wxInfoBar::RestoreParentBackground()
156 {
157 GetParent()->SetOwnBackgroundColour(m_origParentBgCol);
158 }
159
160 void wxInfoBar::DoHide()
161 {
162 ChangeParentBackground();
163 wxON_BLOCK_EXIT_THIS0( wxInfoBar::RestoreParentBackground );
164
165 HideWithEffect(m_hideEffect, m_effectDuration);
166 UpdateParent();
167 }
168
169 void wxInfoBar::DoShow()
170 {
171 // re-layout the parent first so that the window expands into an already
172 // unoccupied by the other controls area: for this we need to change our
173 // internal visibility flag to force Layout() to take us into account (an
174 // alternative solution to this hack would be to temporarily set
175 // wxRESERVE_SPACE_EVEN_IF_HIDDEN flag but it's not really batter)
176
177 // just change the internal flag indicating that the window is visible,
178 // without really showing it
179 wxWindowBase::Show();
180
181 // an extra hack: we want the temporarily uncovered area in which we're
182 // going to expand to look like part of this sibling for a better effect so
183 // temporarily change the background of our parent to the same colour
184 ChangeParentBackground();
185 wxON_BLOCK_EXIT_THIS0( wxInfoBar::RestoreParentBackground );
186
187 // adjust the parent layout to account for us
188 UpdateParent();
189
190 // reset the flag back before really showing the window or it wouldn't be
191 // shown at all because it would believe itself already visible
192 wxWindowBase::Show(false);
193
194
195 // finally do really show the window.
196 ShowWithEffect(m_showEffect, m_effectDuration);
197 }
198
199 void wxInfoBar::ShowMessage(const wxString& msg, int flags)
200 {
201 // first update the controls
202 const int icon = flags & wxICON_MASK;
203 if ( !icon || (icon == wxICON_NONE) )
204 {
205 m_icon->Hide();
206 }
207 else // do show an icon
208 {
209 m_icon->SetBitmap(wxArtProvider::GetMessageBoxIcon(icon));
210 m_icon->Show();
211 }
212
213 // notice the use of EscapeMnemonics() to ensure that "&" come through
214 // correctly
215 m_text->SetLabel(wxControl::EscapeMnemonics(msg));
216
217
218 // then show this entire window if not done yet
219 if ( !IsShown() )
220 {
221 DoShow();
222 }
223 else // we're already shown
224 {
225 // just update the layout to correspond to the new message
226 Layout();
227 }
228 }
229
230 void wxInfoBar::OnButton(wxCommandEvent& WXUNUSED(event))
231 {
232 DoHide();
233 }
234
235 #endif // wxUSE_INFOBAR