]> git.saurik.com Git - wxWidgets.git/blob - src/common/statbar.cpp
don't write the strings to the stream one char at a time, it's *horribly* slow
[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 license
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 m_statusTextStacks[i]->Clear();
238 delete m_statusTextStacks[i];
239 }
240 }
241
242 delete[] m_statusTextStacks;
243 }
244
245 // ----------------------------------------------------------------------------
246 // text stacks
247 // ----------------------------------------------------------------------------
248
249 void wxStatusBarBase::PushStatusText(const wxString& text, int number)
250 {
251 wxListString* st = GetOrCreateStatusStack(number);
252 st->Insert(new wxString(GetStatusText(number)));
253 SetStatusText(text, number);
254 }
255
256 void wxStatusBarBase::PopStatusText(int number)
257 {
258 wxListString *st = GetStatusStack(number);
259 wxCHECK_RET( st, _T("Unbalanced PushStatusText/PopStatusText") );
260 wxListString::Node *top = st->GetFirst();
261
262 SetStatusText(*top->GetData(), number);
263 st->DeleteNode(top);
264 if(st->GetCount() == 0)
265 {
266 delete st;
267 m_statusTextStacks[number] = 0;
268 }
269 }
270
271 wxListString *wxStatusBarBase::GetStatusStack(int i) const
272 {
273 if(!m_statusTextStacks)
274 return 0;
275 return m_statusTextStacks[i];
276 }
277
278 wxListString *wxStatusBarBase::GetOrCreateStatusStack(int i)
279 {
280 if(!m_statusTextStacks)
281 {
282 m_statusTextStacks = new wxListString*[m_nFields];
283
284 size_t j;
285 for(j = 0; j < (size_t)m_nFields; ++j) m_statusTextStacks[j] = 0;
286 }
287
288 if(!m_statusTextStacks[i])
289 {
290 m_statusTextStacks[i] = new wxListString();
291 m_statusTextStacks[i]->DeleteContents(TRUE);
292 }
293
294 return m_statusTextStacks[i];
295 }
296
297 #endif // wxUSE_STATUSBAR
298