]>
Commit | Line | Data |
---|---|---|
1 | /////////////////////////////////////////////////////////////////////////////// | |
2 | // Name: src/common/statbar.cpp | |
3 | // Purpose: wxStatusBarBase implementation | |
4 | // Author: Vadim Zeitlin | |
5 | // Modified by: Francesco Montorsi | |
6 | // Created: 14.10.01 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> | |
9 | // Licence: 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 | const char wxStatusBarNameStr[] = "statusBar"; | |
36 | ||
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 | } | |
105 | ||
106 | // ============================================================================ | |
107 | // wxStatusBarBase implementation | |
108 | // ============================================================================ | |
109 | ||
110 | IMPLEMENT_DYNAMIC_CLASS(wxStatusBar, wxWindow) | |
111 | ||
112 | #include "wx/arrimpl.cpp" // This is a magic incantation which must be done! | |
113 | WX_DEFINE_EXPORTED_OBJARRAY(wxStatusBarPaneArray) | |
114 | ||
115 | ||
116 | // ---------------------------------------------------------------------------- | |
117 | // ctor/dtor | |
118 | // ---------------------------------------------------------------------------- | |
119 | ||
120 | wxStatusBarBase::wxStatusBarBase() | |
121 | { | |
122 | m_bSameWidthForAllPanes = true; | |
123 | } | |
124 | ||
125 | wxStatusBarBase::~wxStatusBarBase() | |
126 | { | |
127 | // notify the frame that it doesn't have a status bar any longer to avoid | |
128 | // dangling pointers | |
129 | wxFrame *frame = wxDynamicCast(GetParent(), wxFrame); | |
130 | if ( frame && frame->GetStatusBar() == this ) | |
131 | frame->SetStatusBar(NULL); | |
132 | } | |
133 | ||
134 | // ---------------------------------------------------------------------------- | |
135 | // field widths | |
136 | // ---------------------------------------------------------------------------- | |
137 | ||
138 | void wxStatusBarBase::SetFieldsCount(int number, const int *widths) | |
139 | { | |
140 | wxCHECK_RET( number > 0, wxT("invalid field number in SetFieldsCount") ); | |
141 | ||
142 | if ( (size_t)number > m_panes.GetCount() ) | |
143 | { | |
144 | wxStatusBarPane newPane; | |
145 | ||
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); | |
150 | } | |
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 | ||
157 | // SetStatusWidths will automatically refresh | |
158 | SetStatusWidths(number, widths); | |
159 | } | |
160 | ||
161 | void wxStatusBarBase::SetStatusWidths(int WXUNUSED_UNLESS_DEBUG(n), | |
162 | const int widths[]) | |
163 | { | |
164 | wxASSERT_MSG( (size_t)n == m_panes.GetCount(), wxT("field number mismatch") ); | |
165 | ||
166 | if (widths == NULL) | |
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++ ) | |
175 | m_panes[i].SetWidth(widths[i]); | |
176 | ||
177 | m_bSameWidthForAllPanes = false; | |
178 | } | |
179 | ||
180 | // update the display after the widths changed | |
181 | Refresh(); | |
182 | } | |
183 | ||
184 | void wxStatusBarBase::SetStatusStyles(int WXUNUSED_UNLESS_DEBUG(n), | |
185 | const int styles[]) | |
186 | { | |
187 | wxCHECK_RET( styles, wxT("NULL pointer in SetStatusStyles") ); | |
188 | ||
189 | wxASSERT_MSG( (size_t)n == m_panes.GetCount(), wxT("field number mismatch") ); | |
190 | ||
191 | for ( size_t i = 0; i < m_panes.GetCount(); i++ ) | |
192 | m_panes[i].SetStyle(styles[i]); | |
193 | ||
194 | // update the display after the widths changed | |
195 | Refresh(); | |
196 | } | |
197 | ||
198 | wxArrayInt wxStatusBarBase::CalculateAbsWidths(wxCoord widthTotal) const | |
199 | { | |
200 | wxArrayInt widths; | |
201 | ||
202 | if ( m_bSameWidthForAllPanes ) | |
203 | { | |
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; | |
209 | ||
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; | |
217 | } | |
218 | } | |
219 | else // do not override explicit pane widths | |
220 | { | |
221 | // calculate the total width of all the fixed width fields and the | |
222 | // total number of var field widths counting with multiplicity | |
223 | size_t nTotalWidth = 0, | |
224 | nVarCount = 0, | |
225 | i; | |
226 | ||
227 | for ( i = 0; i < m_panes.GetCount(); i++ ) | |
228 | { | |
229 | if ( m_panes[i].GetWidth() >= 0 ) | |
230 | nTotalWidth += m_panes[i].GetWidth(); | |
231 | else | |
232 | nVarCount += -m_panes[i].GetWidth(); | |
233 | } | |
234 | ||
235 | // the amount of extra width we have per each var width field | |
236 | int widthExtra = widthTotal - nTotalWidth; | |
237 | ||
238 | // do fill the array | |
239 | for ( i = 0; i < m_panes.GetCount(); i++ ) | |
240 | { | |
241 | if ( m_panes[i].GetWidth() >= 0 ) | |
242 | widths.Add(m_panes[i].GetWidth()); | |
243 | else | |
244 | { | |
245 | int nVarWidth = widthExtra > 0 ? (widthExtra * (-m_panes[i].GetWidth())) / nVarCount : 0; | |
246 | nVarCount += m_panes[i].GetWidth(); | |
247 | widthExtra -= nVarWidth; | |
248 | widths.Add(nVarWidth); | |
249 | } | |
250 | } | |
251 | } | |
252 | ||
253 | return widths; | |
254 | } | |
255 | ||
256 | // ---------------------------------------------------------------------------- | |
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 | |
287 | // ---------------------------------------------------------------------------- | |
288 | ||
289 | void wxStatusBarBase::PushStatusText(const wxString& text, int number) | |
290 | { | |
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); | |
296 | } | |
297 | ||
298 | void wxStatusBarBase::PopStatusText(int number) | |
299 | { | |
300 | wxCHECK_RET( (unsigned)number < m_panes.size(), | |
301 | "invalid status bar field index" ); | |
302 | ||
303 | if ( m_panes[number].PopText() ) | |
304 | DoUpdateStatusText(number); | |
305 | } | |
306 | ||
307 | #endif // wxUSE_STATUSBAR |