Commit | Line | Data |
---|---|---|
71e03035 | 1 | /////////////////////////////////////////////////////////////////////////////// |
3304646d | 2 | // Name: src/common/statbar.cpp |
71e03035 VZ |
3 | // Purpose: wxStatusBarBase implementation |
4 | // Author: Vadim Zeitlin | |
7b6fefbe | 5 | // Modified by: Francesco Montorsi |
71e03035 VZ |
6 | // Created: 14.10.01 |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> | |
526954c5 | 9 | // Licence: 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 | ||
23318a53 | 35 | const char wxStatusBarNameStr[] = "statusBar"; |
53b6d7a2 | 36 | |
6cf68971 VZ |
37 | // ============================================================================ |
38 | // wxStatusBarPane implementation | |
39 | // ============================================================================ | |
40 | ||
41 | bool wxStatusBarPane::SetText(const wxString& text) | |
42 | { | |
43 | if ( text == m_text ) | |
44 | return false; | |
45 | ||
46 | /* | |
47 | If we have a message to restore on the stack, we update it to | |
48 | correspond to the current one so that a sequence of calls such as | |
49 | ||
50 | 1. SetStatusText("foo") | |
51 | 2. PushStatusText("bar") | |
52 | 3. SetStatusText("new foo") | |
53 | 4. PopStatusText() | |
54 | ||
55 | doesn't overwrite the "new foo" which should be shown at the end with | |
56 | the old value "foo". This would be unexpected and hard to avoid, | |
57 | especially when PushStatusText() is used internally by wxWidgets | |
58 | without knowledge of the user program, as it is for showing the menu | |
59 | and toolbar help strings. | |
60 | ||
61 | By updating the top of the stack we ensure that the next call to | |
62 | PopStatusText() basically becomes a NOP without breaking the balance | |
63 | between the calls to push and pop as we would have done if we really | |
64 | called PopStatusText() here. | |
65 | */ | |
66 | if ( !m_arrStack.empty() ) | |
67 | { | |
68 | m_arrStack.back() = text; | |
69 | } | |
70 | ||
71 | m_text = text; | |
72 | ||
73 | return true; | |
74 | } | |
75 | ||
76 | bool wxStatusBarPane::PushText(const wxString& text) | |
77 | { | |
78 | // save the currently shown text | |
79 | m_arrStack.push_back(m_text); | |
80 | ||
81 | // and update the new one if necessary | |
82 | if ( text == m_text ) | |
83 | return false; | |
84 | ||
85 | m_text = text; | |
86 | ||
87 | return true; | |
88 | } | |
89 | ||
90 | bool wxStatusBarPane::PopText() | |
91 | { | |
92 | wxCHECK_MSG( !m_arrStack.empty(), false, "no status message to pop" ); | |
93 | ||
94 | const wxString text = m_arrStack.back(); | |
95 | ||
96 | m_arrStack.pop_back(); | |
97 | ||
98 | if ( text == m_text ) | |
99 | return false; | |
100 | ||
101 | m_text = text; | |
102 | ||
103 | return true; | |
104 | } | |
7b6fefbe | 105 | |
71e03035 VZ |
106 | // ============================================================================ |
107 | // wxStatusBarBase implementation | |
108 | // ============================================================================ | |
109 | ||
a93e536b | 110 | IMPLEMENT_DYNAMIC_CLASS(wxStatusBar, wxWindow) |
71e03035 | 111 | |
0dc8fac2 | 112 | #include "wx/arrimpl.cpp" // This is a magic incantation which must be done! |
b2d76621 | 113 | WX_DEFINE_EXPORTED_OBJARRAY(wxStatusBarPaneArray) |
7b6fefbe FM |
114 | |
115 | ||
71e03035 VZ |
116 | // ---------------------------------------------------------------------------- |
117 | // ctor/dtor | |
118 | // ---------------------------------------------------------------------------- | |
119 | ||
120 | wxStatusBarBase::wxStatusBarBase() | |
121 | { | |
7b6fefbe | 122 | m_bSameWidthForAllPanes = true; |
71e03035 VZ |
123 | } |
124 | ||
125 | wxStatusBarBase::~wxStatusBarBase() | |
126 | { | |
2ab82214 VZ |
127 | // notify the frame that it doesn't have a status bar any longer to avoid |
128 | // dangling pointers | |
67f30682 | 129 | wxFrame *frame = wxDynamicCast(GetParent(), wxFrame); |
2ab82214 | 130 | if ( frame && frame->GetStatusBar() == this ) |
2ab82214 | 131 | frame->SetStatusBar(NULL); |
c2919ab3 VZ |
132 | } |
133 | ||
71e03035 VZ |
134 | // ---------------------------------------------------------------------------- |
135 | // field widths | |
136 | // ---------------------------------------------------------------------------- | |
137 | ||
138 | void wxStatusBarBase::SetFieldsCount(int number, const int *widths) | |
139 | { | |
9a83f860 | 140 | wxCHECK_RET( number > 0, wxT("invalid field number in SetFieldsCount") ); |
71e03035 | 141 | |
7b6fefbe | 142 | if ( (size_t)number > m_panes.GetCount() ) |
71e03035 | 143 | { |
7b6fefbe | 144 | wxStatusBarPane newPane; |
c2919ab3 | 145 | |
7b6fefbe FM |
146 | // add more entries with the default style and zero width |
147 | // (this will be set later) | |
148 | for (size_t i = m_panes.GetCount(); i < (size_t)number; ++i) | |
149 | m_panes.Add(newPane); | |
71e03035 | 150 | } |
7b6fefbe FM |
151 | else if ( (size_t)number < m_panes.GetCount() ) |
152 | { | |
153 | // remove entries in excess | |
154 | m_panes.RemoveAt(number, m_panes.GetCount()-number); | |
155 | } | |
156 | ||
fd3ece57 FM |
157 | // SetStatusWidths will automatically refresh |
158 | SetStatusWidths(number, widths); | |
71e03035 VZ |
159 | } |
160 | ||
161 | void wxStatusBarBase::SetStatusWidths(int WXUNUSED_UNLESS_DEBUG(n), | |
fd3ece57 | 162 | const int widths[]) |
71e03035 | 163 | { |
9a83f860 | 164 | wxASSERT_MSG( (size_t)n == m_panes.GetCount(), wxT("field number mismatch") ); |
71e03035 | 165 | |
54e18afc | 166 | if (widths == NULL) |
fd3ece57 FM |
167 | { |
168 | // special value meaning: override explicit pane widths and make them all | |
169 | // of the same size | |
170 | m_bSameWidthForAllPanes = true; | |
171 | } | |
172 | else | |
173 | { | |
174 | for ( size_t i = 0; i < m_panes.GetCount(); i++ ) | |
6cf68971 | 175 | m_panes[i].SetWidth(widths[i]); |
fd3ece57 FM |
176 | |
177 | m_bSameWidthForAllPanes = false; | |
178 | } | |
71e03035 VZ |
179 | |
180 | // update the display after the widths changed | |
181 | Refresh(); | |
182 | } | |
183 | ||
c2919ab3 | 184 | void wxStatusBarBase::SetStatusStyles(int WXUNUSED_UNLESS_DEBUG(n), |
fd3ece57 | 185 | const int styles[]) |
c2919ab3 | 186 | { |
9a83f860 | 187 | wxCHECK_RET( styles, wxT("NULL pointer in SetStatusStyles") ); |
c2919ab3 | 188 | |
9a83f860 | 189 | wxASSERT_MSG( (size_t)n == m_panes.GetCount(), wxT("field number mismatch") ); |
c2919ab3 | 190 | |
7b6fefbe | 191 | for ( size_t i = 0; i < m_panes.GetCount(); i++ ) |
6cf68971 | 192 | m_panes[i].SetStyle(styles[i]); |
c2919ab3 VZ |
193 | |
194 | // update the display after the widths changed | |
195 | Refresh(); | |
196 | } | |
197 | ||
71e03035 VZ |
198 | wxArrayInt wxStatusBarBase::CalculateAbsWidths(wxCoord widthTotal) const |
199 | { | |
200 | wxArrayInt widths; | |
201 | ||
7b6fefbe | 202 | if ( m_bSameWidthForAllPanes ) |
71e03035 | 203 | { |
7b6fefbe FM |
204 | // Default: all fields have the same width. This is not always |
205 | // possible to do exactly (if widthTotal is not divisible by | |
206 | // m_panes.GetCount()) - if that happens, we distribute the extra | |
207 | // pixels among all fields: | |
208 | int widthToUse = widthTotal; | |
68ab959c | 209 | |
7b6fefbe FM |
210 | for ( size_t i = m_panes.GetCount(); i > 0; i-- ) |
211 | { | |
212 | // divide the unassigned width evently between the | |
213 | // not yet processed fields: | |
214 | int w = widthToUse / i; | |
215 | widths.Add(w); | |
216 | widthToUse -= w; | |
71e03035 VZ |
217 | } |
218 | } | |
7b6fefbe | 219 | else // do not override explicit pane widths |
71e03035 VZ |
220 | { |
221 | // calculate the total width of all the fixed width fields and the | |
222 | // total number of var field widths counting with multiplicity | |
7b6fefbe | 223 | size_t nTotalWidth = 0, |
fd3ece57 FM |
224 | nVarCount = 0, |
225 | i; | |
7b6fefbe FM |
226 | |
227 | for ( i = 0; i < m_panes.GetCount(); i++ ) | |
71e03035 | 228 | { |
b31eaa5c FM |
229 | if ( m_panes[i].GetWidth() >= 0 ) |
230 | nTotalWidth += m_panes[i].GetWidth(); | |
71e03035 | 231 | else |
b31eaa5c | 232 | nVarCount += -m_panes[i].GetWidth(); |
71e03035 VZ |
233 | } |
234 | ||
235 | // the amount of extra width we have per each var width field | |
1a83b9bd | 236 | int widthExtra = widthTotal - nTotalWidth; |
71e03035 VZ |
237 | |
238 | // do fill the array | |
7b6fefbe | 239 | for ( i = 0; i < m_panes.GetCount(); i++ ) |
71e03035 | 240 | { |
b31eaa5c FM |
241 | if ( m_panes[i].GetWidth() >= 0 ) |
242 | widths.Add(m_panes[i].GetWidth()); | |
71e03035 VZ |
243 | else |
244 | { | |
b31eaa5c FM |
245 | int nVarWidth = widthExtra > 0 ? (widthExtra * (-m_panes[i].GetWidth())) / nVarCount : 0; |
246 | nVarCount += m_panes[i].GetWidth(); | |
1a83b9bd VZ |
247 | widthExtra -= nVarWidth; |
248 | widths.Add(nVarWidth); | |
71e03035 VZ |
249 | } |
250 | } | |
251 | } | |
252 | ||
253 | return widths; | |
254 | } | |
255 | ||
1f361cdd | 256 | // ---------------------------------------------------------------------------- |
6cf68971 VZ |
257 | // setting/getting status text |
258 | // ---------------------------------------------------------------------------- | |
259 | ||
260 | void wxStatusBarBase::SetStatusText(const wxString& text, int number) | |
261 | { | |
262 | wxCHECK_RET( (unsigned)number < m_panes.size(), | |
263 | "invalid status bar field index" ); | |
264 | ||
265 | if ( m_panes[number].SetText(text) ) | |
266 | DoUpdateStatusText(number); | |
267 | } | |
268 | ||
269 | wxString wxStatusBarBase::GetStatusText(int number) const | |
270 | { | |
271 | wxCHECK_MSG( (unsigned)number < m_panes.size(), wxString(), | |
272 | "invalid status bar field index" ); | |
273 | ||
274 | return m_panes[number].GetText(); | |
275 | } | |
276 | ||
277 | void wxStatusBarBase::SetEllipsizedFlag(int number, bool isEllipsized) | |
278 | { | |
279 | wxCHECK_RET( (unsigned)number < m_panes.size(), | |
280 | "invalid status bar field index" ); | |
281 | ||
282 | m_panes[number].SetIsEllipsized(isEllipsized); | |
283 | } | |
284 | ||
285 | // ---------------------------------------------------------------------------- | |
286 | // pushing/popping status text | |
1f361cdd MB |
287 | // ---------------------------------------------------------------------------- |
288 | ||
289 | void wxStatusBarBase::PushStatusText(const wxString& text, int number) | |
290 | { | |
6cf68971 VZ |
291 | wxCHECK_RET( (unsigned)number < m_panes.size(), |
292 | "invalid status bar field index" ); | |
293 | ||
294 | if ( m_panes[number].PushText(text) ) | |
295 | DoUpdateStatusText(number); | |
1f361cdd MB |
296 | } |
297 | ||
298 | void wxStatusBarBase::PopStatusText(int number) | |
299 | { | |
6cf68971 VZ |
300 | wxCHECK_RET( (unsigned)number < m_panes.size(), |
301 | "invalid status bar field index" ); | |
302 | ||
303 | if ( m_panes[number].PopText() ) | |
304 | DoUpdateStatusText(number); | |
1f361cdd MB |
305 | } |
306 | ||
71e03035 | 307 | #endif // wxUSE_STATUSBAR |