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