STL-ification patch for wxMSW and wxGTK.
[wxWidgets.git] / src / common / statbar.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: 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 #ifdef __GNUG__
21 #pragma implementation "statbar.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/statusbr.h"
33 #endif //WX_PRECOMP
34
35 #if wxUSE_STATUSBAR
36
37 #include "wx/listimpl.cpp"
38 WX_DEFINE_LIST(wxListString);
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 }
57
58 wxStatusBarBase::~wxStatusBarBase()
59 {
60 FreeWidths();
61 FreeStacks();
62 }
63
64 // ----------------------------------------------------------------------------
65 // widths array handling
66 // ----------------------------------------------------------------------------
67
68 void wxStatusBarBase::InitWidths()
69 {
70 m_statusWidths = NULL;
71 }
72
73 void wxStatusBarBase::FreeWidths()
74 {
75 delete [] m_statusWidths;
76 }
77
78 // ----------------------------------------------------------------------------
79 // field widths
80 // ----------------------------------------------------------------------------
81
82 void wxStatusBarBase::SetFieldsCount(int number, const int *widths)
83 {
84 wxCHECK_RET( number > 0, _T("invalid field number in SetFieldsCount") );
85
86 bool refresh = FALSE;
87
88 if ( number != m_nFields )
89 {
90 // copy stacks if present
91 if(m_statusTextStacks)
92 {
93 wxListString **newStacks = new wxListString*[number];
94 size_t i, j, max = wxMin(number, m_nFields);
95
96 // copy old stacks
97 for(i = 0; i < max; ++i)
98 newStacks[i] = m_statusTextStacks[i];
99 // free old stacks in excess
100 for(j = i; j < (size_t)m_nFields; ++j)
101 {
102 if(m_statusTextStacks[j])
103 {
104 m_statusTextStacks[j]->Clear();
105 delete m_statusTextStacks[j];
106 }
107 }
108 // initialize new stacks to NULL
109 for(j = i; j < (size_t)number; ++j)
110 newStacks[j] = 0;
111
112 m_statusTextStacks = newStacks;
113 }
114
115 m_nFields = number;
116
117 ReinitWidths();
118
119 refresh = TRUE;
120 }
121 //else: keep the old m_statusWidths if we had them
122
123 if ( widths )
124 {
125 SetStatusWidths(number, widths);
126
127 // already done from SetStatusWidths()
128 refresh = FALSE;
129 }
130
131 if ( refresh )
132 Refresh();
133 }
134
135 void wxStatusBarBase::SetStatusWidths(int WXUNUSED_UNLESS_DEBUG(n),
136 const int widths[])
137 {
138 wxCHECK_RET( widths, _T("NULL pointer in SetStatusWidths") );
139
140 wxASSERT_MSG( n == m_nFields, _T("field number mismatch") );
141
142 if ( !m_statusWidths )
143 m_statusWidths = new int[m_nFields];
144
145 for ( int i = 0; i < m_nFields; i++ )
146 {
147 m_statusWidths[i] = widths[i];
148 }
149
150 // update the display after the widths changed
151 Refresh();
152 }
153
154 wxArrayInt wxStatusBarBase::CalculateAbsWidths(wxCoord widthTotal) const
155 {
156 wxArrayInt widths;
157
158 if ( m_statusWidths == NULL )
159 {
160 if ( m_nFields )
161 {
162 // default: all fields have the same width
163 int nWidth = widthTotal / m_nFields;
164 for ( int i = 0; i < m_nFields; i++ )
165 {
166 widths.Add(nWidth);
167 }
168 }
169 //else: we're empty anyhow
170 }
171 else // have explicit status widths
172 {
173 // calculate the total width of all the fixed width fields and the
174 // total number of var field widths counting with multiplicity
175 int nTotalWidth = 0,
176 nVarCount = 0,
177 i;
178 for ( i = 0; i < m_nFields; i++ )
179 {
180 if ( m_statusWidths[i] >= 0 )
181 {
182 nTotalWidth += m_statusWidths[i];
183 }
184 else
185 {
186 nVarCount += -m_statusWidths[i];
187 }
188 }
189
190 // the amount of extra width we have per each var width field
191 int nVarWidth;
192 if ( nVarCount )
193 {
194 int widthExtra = widthTotal - nTotalWidth;
195 nVarWidth = widthExtra > 0 ? widthExtra / nVarCount : 0;
196 }
197 else // no var width fields at all
198 {
199 nVarWidth = 0;
200 }
201
202 // do fill the array
203 for ( i = 0; i < m_nFields; i++ )
204 {
205 if ( m_statusWidths[i] >= 0 )
206 {
207 widths.Add(m_statusWidths[i]);
208 }
209 else
210 {
211 widths.Add(-m_statusWidths[i]*nVarWidth);
212 }
213 }
214 }
215
216 return widths;
217 }
218
219 // ----------------------------------------------------------------------------
220 // text stacks handling
221 // ----------------------------------------------------------------------------
222
223 void wxStatusBarBase::InitStacks()
224 {
225 m_statusTextStacks = NULL;
226 }
227
228 void wxStatusBarBase::FreeStacks()
229 {
230 if(!m_statusTextStacks) return;
231 size_t i;
232
233 for(i = 0; i < (size_t)m_nFields; ++i)
234 {
235 if(m_statusTextStacks[i])
236 {
237 wxListString& t = *m_statusTextStacks[i];
238 WX_CLEAR_LIST(wxListString, t);
239 delete m_statusTextStacks[i];
240 }
241 }
242
243 delete[] m_statusTextStacks;
244 }
245
246 // ----------------------------------------------------------------------------
247 // text stacks
248 // ----------------------------------------------------------------------------
249
250 void wxStatusBarBase::PushStatusText(const wxString& text, int number)
251 {
252 wxListString* st = GetOrCreateStatusStack(number);
253 st->Insert(new wxString(GetStatusText(number)));
254 SetStatusText(text, number);
255 }
256
257 void wxStatusBarBase::PopStatusText(int number)
258 {
259 wxListString *st = GetStatusStack(number);
260 wxCHECK_RET( st, _T("Unbalanced PushStatusText/PopStatusText") );
261 wxListString::compatibility_iterator top = st->GetFirst();
262
263 SetStatusText(*top->GetData(), number);
264 delete top->GetData();
265 st->Erase(top);
266 if(st->GetCount() == 0)
267 {
268 delete st;
269 m_statusTextStacks[number] = 0;
270 }
271 }
272
273 wxListString *wxStatusBarBase::GetStatusStack(int i) const
274 {
275 if(!m_statusTextStacks)
276 return 0;
277 return m_statusTextStacks[i];
278 }
279
280 wxListString *wxStatusBarBase::GetOrCreateStatusStack(int i)
281 {
282 if(!m_statusTextStacks)
283 {
284 m_statusTextStacks = new wxListString*[m_nFields];
285
286 size_t j;
287 for(j = 0; j < (size_t)m_nFields; ++j) m_statusTextStacks[j] = 0;
288 }
289
290 if(!m_statusTextStacks[i])
291 {
292 m_statusTextStacks[i] = new wxListString();
293 }
294
295 return m_statusTextStacks[i];
296 }
297
298 #endif // wxUSE_STATUSBAR
299