1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/statbar.cpp
3 // Purpose: wxStatusBarBase implementation
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // License: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
29 #include "wx/statusbr.h"
35 #include "wx/listimpl.cpp"
36 WX_DEFINE_LIST(wxListString
)
38 const char wxStatusBarNameStr
[] = "statusBar";
40 // ============================================================================
41 // wxStatusBarBase implementation
42 // ============================================================================
44 IMPLEMENT_DYNAMIC_CLASS(wxStatusBar
, wxWindow
)
46 // ----------------------------------------------------------------------------
48 // ----------------------------------------------------------------------------
50 wxStatusBarBase::wxStatusBarBase()
59 wxStatusBarBase::~wxStatusBarBase()
65 // notify the frame that it doesn't have a status bar any longer to avoid
67 wxFrame
*frame
= wxDynamicCast(GetParent(), wxFrame
);
68 if ( frame
&& frame
->GetStatusBar() == this )
70 frame
->SetStatusBar(NULL
);
74 // ----------------------------------------------------------------------------
75 // widths array handling
76 // ----------------------------------------------------------------------------
78 void wxStatusBarBase::InitWidths()
80 m_statusWidths
= NULL
;
83 void wxStatusBarBase::FreeWidths()
85 delete [] m_statusWidths
;
88 // ----------------------------------------------------------------------------
89 // styles array handling
90 // ----------------------------------------------------------------------------
92 void wxStatusBarBase::InitStyles()
94 m_statusStyles
= NULL
;
97 void wxStatusBarBase::FreeStyles()
99 delete [] m_statusStyles
;
102 // ----------------------------------------------------------------------------
104 // ----------------------------------------------------------------------------
106 void wxStatusBarBase::SetFieldsCount(int number
, const int *widths
)
108 wxCHECK_RET( number
> 0, _T("invalid field number in SetFieldsCount") );
110 bool refresh
= false;
112 if ( number
!= m_nFields
)
114 // copy stacks if present
115 if(m_statusTextStacks
)
117 wxListString
**newStacks
= new wxListString
*[number
];
118 size_t i
, j
, max
= wxMin(number
, m_nFields
);
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
)
126 if(m_statusTextStacks
[j
])
128 m_statusTextStacks
[j
]->Clear();
129 delete m_statusTextStacks
[j
];
132 // initialize new stacks to NULL
133 for(j
= i
; j
< (size_t)number
; ++j
)
136 m_statusTextStacks
= newStacks
;
139 // Resize styles array
142 int *oldStyles
= m_statusStyles
;
143 m_statusStyles
= new int[number
];
144 int i
, max
= wxMin(number
, m_nFields
);
147 for (i
= 0; i
< max
; ++i
)
148 m_statusStyles
[i
] = oldStyles
[i
];
150 // initialize new styles to wxSB_NORMAL
151 for (i
= max
; i
< number
; ++i
)
152 m_statusStyles
[i
] = wxSB_NORMAL
;
165 //else: keep the old m_statusWidths if we had them
169 SetStatusWidths(number
, widths
);
171 // already done from SetStatusWidths()
179 void wxStatusBarBase::SetStatusWidths(int WXUNUSED_UNLESS_DEBUG(n
),
182 wxCHECK_RET( widths
, _T("NULL pointer in SetStatusWidths") );
184 wxASSERT_MSG( n
== m_nFields
, _T("field number mismatch") );
186 if ( !m_statusWidths
)
187 m_statusWidths
= new int[m_nFields
];
189 for ( int i
= 0; i
< m_nFields
; i
++ )
191 m_statusWidths
[i
] = widths
[i
];
194 // update the display after the widths changed
198 void wxStatusBarBase::SetStatusStyles(int WXUNUSED_UNLESS_DEBUG(n
),
201 wxCHECK_RET( styles
, _T("NULL pointer in SetStatusStyles") );
203 wxASSERT_MSG( n
== m_nFields
, _T("field number mismatch") );
205 if ( !m_statusStyles
)
206 m_statusStyles
= new int[m_nFields
];
208 for ( int i
= 0; i
< m_nFields
; i
++ )
210 m_statusStyles
[i
] = styles
[i
];
213 // update the display after the widths changed
217 wxArrayInt
wxStatusBarBase::CalculateAbsWidths(wxCoord widthTotal
) const
221 if ( m_statusWidths
== NULL
)
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
229 int widthToUse
= widthTotal
;
231 for ( int i
= m_nFields
; i
> 0; i
-- )
233 // divide the unassigned width evently between the
234 // not yet processed fields:
235 int w
= widthToUse
/ i
;
241 //else: we're empty anyhow
243 else // have explicit status widths
245 // calculate the total width of all the fixed width fields and the
246 // total number of var field widths counting with multiplicity
250 for ( i
= 0; i
< m_nFields
; i
++ )
252 if ( m_statusWidths
[i
] >= 0 )
254 nTotalWidth
+= m_statusWidths
[i
];
258 nVarCount
+= -m_statusWidths
[i
];
262 // the amount of extra width we have per each var width field
263 int widthExtra
= widthTotal
- nTotalWidth
;
266 for ( i
= 0; i
< m_nFields
; i
++ )
268 if ( m_statusWidths
[i
] >= 0 )
270 widths
.Add(m_statusWidths
[i
]);
274 int nVarWidth
= widthExtra
> 0 ? (widthExtra
* -m_statusWidths
[i
]) / nVarCount
: 0;
275 nVarCount
+= m_statusWidths
[i
];
276 widthExtra
-= nVarWidth
;
277 widths
.Add(nVarWidth
);
285 // ----------------------------------------------------------------------------
286 // text stacks handling
287 // ----------------------------------------------------------------------------
289 void wxStatusBarBase::InitStacks()
291 m_statusTextStacks
= NULL
;
294 void wxStatusBarBase::FreeStacks()
296 if ( !m_statusTextStacks
)
299 for ( size_t i
= 0; i
< (size_t)m_nFields
; ++i
)
301 if ( m_statusTextStacks
[i
] )
303 wxListString
& t
= *m_statusTextStacks
[i
];
304 WX_CLEAR_LIST(wxListString
, t
);
305 delete m_statusTextStacks
[i
];
309 delete[] m_statusTextStacks
;
312 // ----------------------------------------------------------------------------
314 // ----------------------------------------------------------------------------
316 void wxStatusBarBase::PushStatusText(const wxString
& text
, int number
)
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
);
324 SetStatusText(text
, number
);
327 void wxStatusBarBase::PopStatusText(int number
)
329 wxListString
*st
= GetStatusStack(number
);
330 wxCHECK_RET( st
, _T("Unbalanced PushStatusText/PopStatusText") );
331 wxListString::compatibility_iterator top
= st
->GetFirst();
333 SetStatusText(*top
->GetData(), number
);
334 delete top
->GetData();
336 if(st
->GetCount() == 0)
339 m_statusTextStacks
[number
] = 0;
343 wxListString
*wxStatusBarBase::GetStatusStack(int i
) const
345 if(!m_statusTextStacks
)
347 return m_statusTextStacks
[i
];
350 wxListString
*wxStatusBarBase::GetOrCreateStatusStack(int i
)
352 if(!m_statusTextStacks
)
354 m_statusTextStacks
= new wxListString
*[m_nFields
];
357 for(j
= 0; j
< (size_t)m_nFields
; ++j
) m_statusTextStacks
[j
] = 0;
360 if(!m_statusTextStacks
[i
])
362 m_statusTextStacks
[i
] = new wxListString();
365 return m_statusTextStacks
[i
];
368 #endif // wxUSE_STATUSBAR