1 |
william |
31 |
/////////////////////////////////////////////////////////////////////////////// |
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: statbar.cpp 42171 2006-10-20 14:54:14Z VS $ |
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. This is not always |
226 |
|
|
// possible to do exactly (if widthTotal is not divisible by |
227 |
|
|
// m_nFields) - if that happens, we distribute the extra pixels |
228 |
|
|
// among all fields: |
229 |
|
|
int widthToUse = widthTotal; |
230 |
|
|
|
231 |
|
|
for ( int i = m_nFields; i > 0; i-- ) |
232 |
|
|
{ |
233 |
|
|
// divide the unassigned width evently between the |
234 |
|
|
// not yet processed fields: |
235 |
|
|
int w = widthToUse / i; |
236 |
|
|
widths.Add(w); |
237 |
|
|
widthToUse -= w; |
238 |
|
|
} |
239 |
|
|
|
240 |
|
|
} |
241 |
|
|
//else: we're empty anyhow |
242 |
|
|
} |
243 |
|
|
else // have explicit status widths |
244 |
|
|
{ |
245 |
|
|
// calculate the total width of all the fixed width fields and the |
246 |
|
|
// total number of var field widths counting with multiplicity |
247 |
|
|
int nTotalWidth = 0, |
248 |
|
|
nVarCount = 0, |
249 |
|
|
i; |
250 |
|
|
for ( i = 0; i < m_nFields; i++ ) |
251 |
|
|
{ |
252 |
|
|
if ( m_statusWidths[i] >= 0 ) |
253 |
|
|
{ |
254 |
|
|
nTotalWidth += m_statusWidths[i]; |
255 |
|
|
} |
256 |
|
|
else |
257 |
|
|
{ |
258 |
|
|
nVarCount += -m_statusWidths[i]; |
259 |
|
|
} |
260 |
|
|
} |
261 |
|
|
|
262 |
|
|
// the amount of extra width we have per each var width field |
263 |
|
|
int widthExtra = widthTotal - nTotalWidth; |
264 |
|
|
|
265 |
|
|
// do fill the array |
266 |
|
|
for ( i = 0; i < m_nFields; i++ ) |
267 |
|
|
{ |
268 |
|
|
if ( m_statusWidths[i] >= 0 ) |
269 |
|
|
{ |
270 |
|
|
widths.Add(m_statusWidths[i]); |
271 |
|
|
} |
272 |
|
|
else |
273 |
|
|
{ |
274 |
|
|
int nVarWidth = widthExtra > 0 ? (widthExtra * -m_statusWidths[i]) / nVarCount : 0; |
275 |
|
|
nVarCount += m_statusWidths[i]; |
276 |
|
|
widthExtra -= nVarWidth; |
277 |
|
|
widths.Add(nVarWidth); |
278 |
|
|
} |
279 |
|
|
} |
280 |
|
|
} |
281 |
|
|
|
282 |
|
|
return widths; |
283 |
|
|
} |
284 |
|
|
|
285 |
|
|
// ---------------------------------------------------------------------------- |
286 |
|
|
// text stacks handling |
287 |
|
|
// ---------------------------------------------------------------------------- |
288 |
|
|
|
289 |
|
|
void wxStatusBarBase::InitStacks() |
290 |
|
|
{ |
291 |
|
|
m_statusTextStacks = NULL; |
292 |
|
|
} |
293 |
|
|
|
294 |
|
|
void wxStatusBarBase::FreeStacks() |
295 |
|
|
{ |
296 |
|
|
if ( !m_statusTextStacks ) |
297 |
|
|
return; |
298 |
|
|
|
299 |
|
|
for ( size_t i = 0; i < (size_t)m_nFields; ++i ) |
300 |
|
|
{ |
301 |
|
|
if ( m_statusTextStacks[i] ) |
302 |
|
|
{ |
303 |
|
|
wxListString& t = *m_statusTextStacks[i]; |
304 |
|
|
WX_CLEAR_LIST(wxListString, t); |
305 |
|
|
delete m_statusTextStacks[i]; |
306 |
|
|
} |
307 |
|
|
} |
308 |
|
|
|
309 |
|
|
delete[] m_statusTextStacks; |
310 |
|
|
} |
311 |
|
|
|
312 |
|
|
// ---------------------------------------------------------------------------- |
313 |
|
|
// text stacks |
314 |
|
|
// ---------------------------------------------------------------------------- |
315 |
|
|
|
316 |
|
|
void wxStatusBarBase::PushStatusText(const wxString& text, int number) |
317 |
|
|
{ |
318 |
|
|
wxListString* st = GetOrCreateStatusStack(number); |
319 |
|
|
// This long-winded way around avoids an internal compiler error |
320 |
|
|
// in VC++ 6 with RTTI enabled |
321 |
|
|
wxString tmp1(GetStatusText(number)); |
322 |
|
|
wxString* tmp = new wxString(tmp1); |
323 |
|
|
st->Insert(tmp); |
324 |
|
|
SetStatusText(text, number); |
325 |
|
|
} |
326 |
|
|
|
327 |
|
|
void wxStatusBarBase::PopStatusText(int number) |
328 |
|
|
{ |
329 |
|
|
wxListString *st = GetStatusStack(number); |
330 |
|
|
wxCHECK_RET( st, _T("Unbalanced PushStatusText/PopStatusText") ); |
331 |
|
|
wxListString::compatibility_iterator top = st->GetFirst(); |
332 |
|
|
|
333 |
|
|
SetStatusText(*top->GetData(), number); |
334 |
|
|
delete top->GetData(); |
335 |
|
|
st->Erase(top); |
336 |
|
|
if(st->GetCount() == 0) |
337 |
|
|
{ |
338 |
|
|
delete st; |
339 |
|
|
m_statusTextStacks[number] = 0; |
340 |
|
|
} |
341 |
|
|
} |
342 |
|
|
|
343 |
|
|
wxListString *wxStatusBarBase::GetStatusStack(int i) const |
344 |
|
|
{ |
345 |
|
|
if(!m_statusTextStacks) |
346 |
|
|
return 0; |
347 |
|
|
return m_statusTextStacks[i]; |
348 |
|
|
} |
349 |
|
|
|
350 |
|
|
wxListString *wxStatusBarBase::GetOrCreateStatusStack(int i) |
351 |
|
|
{ |
352 |
|
|
if(!m_statusTextStacks) |
353 |
|
|
{ |
354 |
|
|
m_statusTextStacks = new wxListString*[m_nFields]; |
355 |
|
|
|
356 |
|
|
size_t j; |
357 |
|
|
for(j = 0; j < (size_t)m_nFields; ++j) m_statusTextStacks[j] = 0; |
358 |
|
|
} |
359 |
|
|
|
360 |
|
|
if(!m_statusTextStacks[i]) |
361 |
|
|
{ |
362 |
|
|
m_statusTextStacks[i] = new wxListString(); |
363 |
|
|
} |
364 |
|
|
|
365 |
|
|
return m_statusTextStacks[i]; |
366 |
|
|
} |
367 |
|
|
|
368 |
|
|
#endif // wxUSE_STATUSBAR |