]> git.saurik.com Git - wxWidgets.git/blame - src/common/statbar.cpp
Added wxVariantData::Clone and wxVariant::Unshare
[wxWidgets.git] / src / common / statbar.cpp
CommitLineData
71e03035 1///////////////////////////////////////////////////////////////////////////////
3304646d 2// Name: src/common/statbar.cpp
71e03035
VZ
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>
65571936 9// License: wxWindows licence
71e03035
VZ
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
71e03035
VZ
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
53b6d7a2
PC
27#if wxUSE_STATUSBAR
28
3304646d
WS
29#include "wx/statusbr.h"
30
71e03035 31#ifndef WX_PRECOMP
e9a05074 32 #include "wx/frame.h"
71e03035
VZ
33#endif //WX_PRECOMP
34
1f361cdd 35#include "wx/listimpl.cpp"
259c43f6 36WX_DEFINE_LIST(wxListString)
1f361cdd 37
53b6d7a2
PC
38const wxChar wxStatusBarNameStr[] = wxT("statusBar");
39
71e03035
VZ
40// ============================================================================
41// wxStatusBarBase implementation
42// ============================================================================
43
a93e536b 44IMPLEMENT_DYNAMIC_CLASS(wxStatusBar, wxWindow)
71e03035
VZ
45
46// ----------------------------------------------------------------------------
47// ctor/dtor
48// ----------------------------------------------------------------------------
49
50wxStatusBarBase::wxStatusBarBase()
51{
52 m_nFields = 0;
53
54 InitWidths();
1f361cdd 55 InitStacks();
c2919ab3 56 InitStyles();
71e03035
VZ
57}
58
59wxStatusBarBase::~wxStatusBarBase()
60{
61 FreeWidths();
1f361cdd 62 FreeStacks();
97152f78 63 FreeStyles();
2ab82214
VZ
64
65 // notify the frame that it doesn't have a status bar any longer to avoid
66 // dangling pointers
b2e3be1c 67 wxFrame *frame = wxDynamicCast(GetParent(), wxFrame);
2ab82214
VZ
68 if ( frame && frame->GetStatusBar() == this )
69 {
70 frame->SetStatusBar(NULL);
71 }
71e03035
VZ
72}
73
74// ----------------------------------------------------------------------------
75// widths array handling
76// ----------------------------------------------------------------------------
77
78void wxStatusBarBase::InitWidths()
79{
80 m_statusWidths = NULL;
81}
82
83void wxStatusBarBase::FreeWidths()
84{
85 delete [] m_statusWidths;
86}
87
c2919ab3
VZ
88// ----------------------------------------------------------------------------
89// styles array handling
90// ----------------------------------------------------------------------------
91
92void wxStatusBarBase::InitStyles()
93{
94 m_statusStyles = NULL;
95}
96
97void wxStatusBarBase::FreeStyles()
98{
99 delete [] m_statusStyles;
100}
101
71e03035
VZ
102// ----------------------------------------------------------------------------
103// field widths
104// ----------------------------------------------------------------------------
105
106void wxStatusBarBase::SetFieldsCount(int number, const int *widths)
107{
108 wxCHECK_RET( number > 0, _T("invalid field number in SetFieldsCount") );
109
d775fa82 110 bool refresh = false;
71e03035
VZ
111
112 if ( number != m_nFields )
113 {
1f361cdd
MB
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
c2919ab3
VZ
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
71e03035
VZ
159 m_nFields = number;
160
161 ReinitWidths();
162
d775fa82 163 refresh = true;
71e03035
VZ
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()
d775fa82 172 refresh = false;
71e03035
VZ
173 }
174
175 if ( refresh )
176 Refresh();
177}
178
179void 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
c2919ab3
VZ
198void 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
71e03035
VZ
217wxArrayInt wxStatusBarBase::CalculateAbsWidths(wxCoord widthTotal) const
218{
219 wxArrayInt widths;
220
221 if ( m_statusWidths == NULL )
222 {
5057e659 223 if ( m_nFields )
71e03035 224 {
68ab959c
VS
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-- )
5057e659 232 {
68ab959c
VS
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;
5057e659 238 }
68ab959c 239
71e03035 240 }
5057e659 241 //else: we're empty anyhow
71e03035
VZ
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
1a83b9bd 263 int widthExtra = widthTotal - nTotalWidth;
71e03035
VZ
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 {
1a83b9bd
VZ
274 int nVarWidth = widthExtra > 0 ? (widthExtra * -m_statusWidths[i]) / nVarCount : 0;
275 nVarCount += m_statusWidths[i];
276 widthExtra -= nVarWidth;
277 widths.Add(nVarWidth);
71e03035
VZ
278 }
279 }
280 }
281
282 return widths;
283}
284
1f361cdd
MB
285// ----------------------------------------------------------------------------
286// text stacks handling
287// ----------------------------------------------------------------------------
288
289void wxStatusBarBase::InitStacks()
290{
291 m_statusTextStacks = NULL;
292}
293
294void wxStatusBarBase::FreeStacks()
295{
97152f78
VZ
296 if ( !m_statusTextStacks )
297 return;
1f361cdd 298
97152f78 299 for ( size_t i = 0; i < (size_t)m_nFields; ++i )
1f361cdd 300 {
97152f78 301 if ( m_statusTextStacks[i] )
1f361cdd 302 {
222ed1d6
MB
303 wxListString& t = *m_statusTextStacks[i];
304 WX_CLEAR_LIST(wxListString, t);
1f361cdd
MB
305 delete m_statusTextStacks[i];
306 }
307 }
308
309 delete[] m_statusTextStacks;
310}
311
312// ----------------------------------------------------------------------------
313// text stacks
314// ----------------------------------------------------------------------------
315
316void wxStatusBarBase::PushStatusText(const wxString& text, int number)
317{
318 wxListString* st = GetOrCreateStatusStack(number);
7d2d5d81
JS
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);
1f361cdd
MB
324 SetStatusText(text, number);
325}
326
327void wxStatusBarBase::PopStatusText(int number)
328{
329 wxListString *st = GetStatusStack(number);
330 wxCHECK_RET( st, _T("Unbalanced PushStatusText/PopStatusText") );
222ed1d6 331 wxListString::compatibility_iterator top = st->GetFirst();
1f361cdd
MB
332
333 SetStatusText(*top->GetData(), number);
222ed1d6
MB
334 delete top->GetData();
335 st->Erase(top);
1f361cdd
MB
336 if(st->GetCount() == 0)
337 {
338 delete st;
339 m_statusTextStacks[number] = 0;
340 }
341}
342
343wxListString *wxStatusBarBase::GetStatusStack(int i) const
344{
345 if(!m_statusTextStacks)
346 return 0;
347 return m_statusTextStacks[i];
348}
349
350wxListString *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();
1f361cdd
MB
363 }
364
365 return m_statusTextStacks[i];
366}
367
71e03035 368#endif // wxUSE_STATUSBAR