]> git.saurik.com Git - wxWidgets.git/blob - src/common/statbar.cpp
fix for handling from Francesco
[wxWidgets.git] / src / common / statbar.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/statbar.cpp
3 // Purpose: wxStatusBarBase implementation
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 14.10.01
7 // RCS-ID: $Id$
8 // Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // License: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #if wxUSE_STATUSBAR
28
29 #include "wx/statusbr.h"
30
31 #ifndef WX_PRECOMP
32 #include "wx/frame.h"
33 #endif //WX_PRECOMP
34
35 #include "wx/listimpl.cpp"
36 WX_DEFINE_LIST(wxListString)
37
38 const wxChar wxStatusBarNameStr[] = wxT("statusBar");
39
40 // ============================================================================
41 // wxStatusBarBase implementation
42 // ============================================================================
43
44 IMPLEMENT_DYNAMIC_CLASS(wxStatusBar, wxWindow)
45
46 // ----------------------------------------------------------------------------
47 // ctor/dtor
48 // ----------------------------------------------------------------------------
49
50 wxStatusBarBase::wxStatusBarBase()
51 {
52 m_nFields = 0;
53
54 InitWidths();
55 InitStacks();
56 InitStyles();
57 }
58
59 wxStatusBarBase::~wxStatusBarBase()
60 {
61 FreeWidths();
62 FreeStacks();
63 FreeStyles();
64
65 // notify the frame that it doesn't have a status bar any longer to avoid
66 // dangling pointers
67 wxFrame *frame = wxDynamicCast(GetParent(), wxFrame);
68 if ( frame && frame->GetStatusBar() == this )
69 {
70 frame->SetStatusBar(NULL);
71 }
72 }
73
74 // ----------------------------------------------------------------------------
75 // widths array handling
76 // ----------------------------------------------------------------------------
77
78 void wxStatusBarBase::InitWidths()
79 {
80 m_statusWidths = NULL;
81 }
82
83 void wxStatusBarBase::FreeWidths()
84 {
85 delete [] m_statusWidths;
86 }
87
88 // ----------------------------------------------------------------------------
89 // styles array handling
90 // ----------------------------------------------------------------------------
91
92 void wxStatusBarBase::InitStyles()
93 {
94 m_statusStyles = NULL;
95 }
96
97 void wxStatusBarBase::FreeStyles()
98 {
99 delete [] m_statusStyles;
100 }
101
102 // ----------------------------------------------------------------------------
103 // field widths
104 // ----------------------------------------------------------------------------
105
106 void wxStatusBarBase::SetFieldsCount(int number, const int *widths)
107 {
108 wxCHECK_RET( number > 0, _T("invalid field number in SetFieldsCount") );
109
110 bool refresh = false;
111
112 if ( number != m_nFields )
113 {
114 // copy stacks if present
115 if(m_statusTextStacks)
116 {
117 wxListString **newStacks = new wxListString*[number];
118 size_t i, j, max = wxMin(number, m_nFields);
119
120 // copy old stacks
121 for(i = 0; i < max; ++i)
122 newStacks[i] = m_statusTextStacks[i];
123 // free old stacks in excess
124 for(j = i; j < (size_t)m_nFields; ++j)
125 {
126 if(m_statusTextStacks[j])
127 {
128 m_statusTextStacks[j]->Clear();
129 delete m_statusTextStacks[j];
130 }
131 }
132 // initialize new stacks to NULL
133 for(j = i; j < (size_t)number; ++j)
134 newStacks[j] = 0;
135
136 m_statusTextStacks = newStacks;
137 }
138
139 // Resize styles array
140 if (m_statusStyles)
141 {
142 int *oldStyles = m_statusStyles;
143 m_statusStyles = new int[number];
144 int i, max = wxMin(number, m_nFields);
145
146 // copy old styles
147 for (i = 0; i < max; ++i)
148 m_statusStyles[i] = oldStyles[i];
149
150 // initialize new styles to wxSB_NORMAL
151 for (i = max; i < number; ++i)
152 m_statusStyles[i] = wxSB_NORMAL;
153
154 // free old styles
155 delete [] oldStyles;
156 }
157
158
159 m_nFields = number;
160
161 ReinitWidths();
162
163 refresh = true;
164 }
165 //else: keep the old m_statusWidths if we had them
166
167 if ( widths )
168 {
169 SetStatusWidths(number, widths);
170
171 // already done from SetStatusWidths()
172 refresh = false;
173 }
174
175 if ( refresh )
176 Refresh();
177 }
178
179 void wxStatusBarBase::SetStatusWidths(int WXUNUSED_UNLESS_DEBUG(n),
180 const int widths[])
181 {
182 wxCHECK_RET( widths, _T("NULL pointer in SetStatusWidths") );
183
184 wxASSERT_MSG( n == m_nFields, _T("field number mismatch") );
185
186 if ( !m_statusWidths )
187 m_statusWidths = new int[m_nFields];
188
189 for ( int i = 0; i < m_nFields; i++ )
190 {
191 m_statusWidths[i] = widths[i];
192 }
193
194 // update the display after the widths changed
195 Refresh();
196 }
197
198 void wxStatusBarBase::SetStatusStyles(int WXUNUSED_UNLESS_DEBUG(n),
199 const int styles[])
200 {
201 wxCHECK_RET( styles, _T("NULL pointer in SetStatusStyles") );
202
203 wxASSERT_MSG( n == m_nFields, _T("field number mismatch") );
204
205 if ( !m_statusStyles )
206 m_statusStyles = new int[m_nFields];
207
208 for ( int i = 0; i < m_nFields; i++ )
209 {
210 m_statusStyles[i] = styles[i];
211 }
212
213 // update the display after the widths changed
214 Refresh();
215 }
216
217 wxArrayInt wxStatusBarBase::CalculateAbsWidths(wxCoord widthTotal) const
218 {
219 wxArrayInt widths;
220
221 if ( m_statusWidths == NULL )
222 {
223 if ( m_nFields )
224 {
225 // default: all fields have the same width
226 int nWidth = widthTotal / m_nFields;
227 for ( int i = 0; i < m_nFields; i++ )
228 {
229 widths.Add(nWidth);
230 }
231 }
232 //else: we're empty anyhow
233 }
234 else // have explicit status widths
235 {
236 // calculate the total width of all the fixed width fields and the
237 // total number of var field widths counting with multiplicity
238 int nTotalWidth = 0,
239 nVarCount = 0,
240 i;
241 for ( i = 0; i < m_nFields; i++ )
242 {
243 if ( m_statusWidths[i] >= 0 )
244 {
245 nTotalWidth += m_statusWidths[i];
246 }
247 else
248 {
249 nVarCount += -m_statusWidths[i];
250 }
251 }
252
253 // the amount of extra width we have per each var width field
254 int widthExtra = widthTotal - nTotalWidth;
255
256 // do fill the array
257 for ( i = 0; i < m_nFields; i++ )
258 {
259 if ( m_statusWidths[i] >= 0 )
260 {
261 widths.Add(m_statusWidths[i]);
262 }
263 else
264 {
265 int nVarWidth = widthExtra > 0 ? (widthExtra * -m_statusWidths[i]) / nVarCount : 0;
266 nVarCount += m_statusWidths[i];
267 widthExtra -= nVarWidth;
268 widths.Add(nVarWidth);
269 }
270 }
271 }
272
273 return widths;
274 }
275
276 // ----------------------------------------------------------------------------
277 // text stacks handling
278 // ----------------------------------------------------------------------------
279
280 void wxStatusBarBase::InitStacks()
281 {
282 m_statusTextStacks = NULL;
283 }
284
285 void wxStatusBarBase::FreeStacks()
286 {
287 if ( !m_statusTextStacks )
288 return;
289
290 for ( size_t i = 0; i < (size_t)m_nFields; ++i )
291 {
292 if ( m_statusTextStacks[i] )
293 {
294 wxListString& t = *m_statusTextStacks[i];
295 WX_CLEAR_LIST(wxListString, t);
296 delete m_statusTextStacks[i];
297 }
298 }
299
300 delete[] m_statusTextStacks;
301 }
302
303 // ----------------------------------------------------------------------------
304 // text stacks
305 // ----------------------------------------------------------------------------
306
307 void wxStatusBarBase::PushStatusText(const wxString& text, int number)
308 {
309 wxListString* st = GetOrCreateStatusStack(number);
310 // This long-winded way around avoids an internal compiler error
311 // in VC++ 6 with RTTI enabled
312 wxString tmp1(GetStatusText(number));
313 wxString* tmp = new wxString(tmp1);
314 st->Insert(tmp);
315 SetStatusText(text, number);
316 }
317
318 void wxStatusBarBase::PopStatusText(int number)
319 {
320 wxListString *st = GetStatusStack(number);
321 wxCHECK_RET( st, _T("Unbalanced PushStatusText/PopStatusText") );
322 wxListString::compatibility_iterator top = st->GetFirst();
323
324 SetStatusText(*top->GetData(), number);
325 delete top->GetData();
326 st->Erase(top);
327 if(st->GetCount() == 0)
328 {
329 delete st;
330 m_statusTextStacks[number] = 0;
331 }
332 }
333
334 wxListString *wxStatusBarBase::GetStatusStack(int i) const
335 {
336 if(!m_statusTextStacks)
337 return 0;
338 return m_statusTextStacks[i];
339 }
340
341 wxListString *wxStatusBarBase::GetOrCreateStatusStack(int i)
342 {
343 if(!m_statusTextStacks)
344 {
345 m_statusTextStacks = new wxListString*[m_nFields];
346
347 size_t j;
348 for(j = 0; j < (size_t)m_nFields; ++j) m_statusTextStacks[j] = 0;
349 }
350
351 if(!m_statusTextStacks[i])
352 {
353 m_statusTextStacks[i] = new wxListString();
354 }
355
356 return m_statusTextStacks[i];
357 }
358
359 #endif // wxUSE_STATUSBAR