Include wx/statusbr.h according to precompiled headers of wx/wx.h (with other minor...
[wxWidgets.git] / src / univ / statusbr.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/univ/statusbr.cpp
3 // Purpose: wxStatusBar implementation
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 14.10.01
7 // RCS-ID: $Id$
8 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #if wxUSE_STATUSBAR
27
28 #include "wx/statusbr.h"
29
30 #ifndef WX_PRECOMP
31 #include "wx/settings.h"
32 #include "wx/dcclient.h"
33 #endif
34
35 #include "wx/toplevel.h"
36
37 #include "wx/univ/renderer.h"
38
39 // ============================================================================
40 // implementation
41 // ============================================================================
42
43 BEGIN_EVENT_TABLE(wxStatusBarUniv, wxStatusBarBase)
44 EVT_SIZE(wxStatusBarUniv::OnSize)
45
46 WX_EVENT_TABLE_INPUT_CONSUMER(wxStatusBarUniv)
47 END_EVENT_TABLE()
48
49 WX_FORWARD_TO_INPUT_CONSUMER(wxStatusBarUniv)
50
51 // ----------------------------------------------------------------------------
52 // creation
53 // ----------------------------------------------------------------------------
54
55 void wxStatusBarUniv::Init()
56 {
57 }
58
59 bool wxStatusBarUniv::Create(wxWindow *parent,
60 wxWindowID id,
61 long style,
62 const wxString& name)
63 {
64 if ( !wxWindow::Create(parent, id,
65 wxDefaultPosition, wxDefaultSize,
66 style, name) )
67 {
68 return false;
69 }
70
71 SetFieldsCount(1);
72
73 CreateInputHandler(wxINP_HANDLER_STATUSBAR);
74
75 SetSize(DoGetBestSize());
76
77 return true;
78 }
79
80 // ----------------------------------------------------------------------------
81 // drawing
82 // ----------------------------------------------------------------------------
83
84 wxRect wxStatusBarUniv::GetTotalFieldRect(wxCoord *borderBetweenFields)
85 {
86 wxRect rect = GetClientRect();
87
88 // no, don't do this - the borders are meant to be inside this rect
89 // wxSize sizeBorders =
90 m_renderer->GetStatusBarBorders(borderBetweenFields);
91 //rect.Deflate(sizeBorders.x, sizeBorders.y);
92
93 // recalc the field widths if needed
94 if ( m_widthsAbs.IsEmpty() )
95 {
96 // the total width for the fields doesn't include the borders between
97 // them
98 m_widthsAbs = CalculateAbsWidths(rect.width -
99 *borderBetweenFields*(m_nFields - 1));
100 }
101
102 return rect;
103 }
104
105 void wxStatusBarUniv::DoDraw(wxControlRenderer *renderer)
106 {
107 // get the fields rect
108 wxCoord borderBetweenFields;
109 wxRect rect = GetTotalFieldRect(&borderBetweenFields);
110
111 // prepare the DC
112 wxDC& dc = renderer->GetDC();
113 dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
114
115 // do draw the fields
116 int flags = IsEnabled() ? 0 : (int)wxCONTROL_DISABLED;
117 for ( int n = 0; n < m_nFields; n++ )
118 {
119 rect.width = m_widthsAbs[n];
120
121 if ( IsExposed(rect) )
122 {
123 wxTopLevelWindow *parentTLW = wxDynamicCast(GetParent(), wxTopLevelWindow);
124
125 // the size grip may be drawn only on the last field and only if we
126 // have the corresponding style and even then only if we really can
127 // resize this frame
128 if ( n == m_nFields - 1 &&
129 HasFlag(wxST_SIZEGRIP) &&
130 GetParent()->HasFlag(wxRESIZE_BORDER) &&
131 parentTLW && !parentTLW->IsMaximized() )
132 {
133 // NB: we use wxCONTROL_ISDEFAULT for this because it doesn't
134 // have any meaning for the status bar otherwise anyhow
135 // (it's still ugly, of course, but there are too few flags
136 // to squander them for things like this)
137 flags |= wxCONTROL_ISDEFAULT;
138 }
139
140 int style;
141 if (m_statusStyles)
142 style = m_statusStyles[n];
143 else
144 style = wxSB_NORMAL;
145 m_renderer->DrawStatusField(dc, rect, m_statusText[n], flags, style);
146 }
147
148 rect.x += rect.width + borderBetweenFields;
149 }
150 }
151
152 void wxStatusBarUniv::RefreshField(int i)
153 {
154 wxRect rect;
155 if ( GetFieldRect(i, rect) )
156 {
157 RefreshRect(rect);
158 }
159 }
160
161 // ----------------------------------------------------------------------------
162 // fields text
163 // ----------------------------------------------------------------------------
164
165 void wxStatusBarUniv::SetStatusText(const wxString& text, int number)
166 {
167 wxCHECK_RET( number >= 0 && number < m_nFields,
168 _T("invalid status bar field index in SetStatusText()") );
169
170 if ( text == m_statusText[number] )
171 {
172 // nothing changed
173 return;
174 }
175
176 m_statusText[number] = text;
177
178 RefreshField(number);
179 }
180
181 wxString wxStatusBarUniv::GetStatusText(int number) const
182 {
183 wxCHECK_MSG( number >= 0 && number < m_nFields, wxEmptyString,
184 _T("invalid status bar field index") );
185
186 return m_statusText[number];
187 }
188
189 // ----------------------------------------------------------------------------
190 // fields count/widths
191 // ----------------------------------------------------------------------------
192
193 void wxStatusBarUniv::SetFieldsCount(int number, const int *widths)
194 {
195 m_statusText.SetCount(number);
196 wxStatusBarBase::SetFieldsCount(number, widths);
197 m_widthsAbs.Empty();
198 }
199
200 void wxStatusBarUniv::SetStatusWidths(int n, const int widths[])
201 {
202 wxStatusBarBase::SetStatusWidths(n, widths);
203
204 m_widthsAbs.Empty();
205 }
206
207 // ----------------------------------------------------------------------------
208 // geometry
209 // ----------------------------------------------------------------------------
210
211 void wxStatusBarUniv::OnSize(wxSizeEvent& event)
212 {
213 // we don't need to refresh the fields whose width didn't change, so find
214 // the first field whose width did change and refresh starting from it
215 int field;
216 if ( m_statusWidths )
217 {
218 for ( field = 0; field < m_nFields; field++ )
219 {
220 if ( m_statusWidths[field] < 0 )
221 {
222 // var width field
223 break;
224 }
225 }
226 }
227 else // all fields have the same width
228 {
229 // hence all fields widths have changed
230 field = 0;
231 }
232
233 if ( field < m_nFields )
234 {
235 // call this before invalidating the old widths as we want to use them,
236 // not the new ones
237 wxRect rect = DoGetFieldRect(field);
238
239 // invalidate the widths, we'll have to recalc them
240 m_widthsAbs.Empty();
241
242 // refresh everything after the first invalid field
243 rect.y = 0;
244 rect.SetRight(event.GetSize().x);
245 rect.height = event.GetSize().y;
246 RefreshRect(rect);
247 }
248
249 event.Skip();
250 }
251
252 bool wxStatusBarUniv::GetFieldRect(int n, wxRect& rect) const
253 {
254 wxCHECK_MSG( n >= 0 && n < m_nFields, false,
255 _T("invalid field index in GetFieldRect()") );
256
257 // this is a fix for a bug exhibited by the statbar sample: if
258 // GetFieldRect() is called from the derived class OnSize() handler, then
259 // our geometry info is wrong as our OnSize() didn't invalidate m_widthsAbs
260 // yet - so recalc it just in case
261 wxConstCast(this, wxStatusBarUniv)->m_widthsAbs.Empty();
262
263 rect = DoGetFieldRect(n);
264
265 return true;
266 }
267
268 wxRect wxStatusBarUniv::DoGetFieldRect(int n) const
269 {
270 wxStatusBarUniv *self = wxConstCast(this, wxStatusBarUniv);
271
272 wxCoord borderBetweenFields;
273 wxRect rect = self->GetTotalFieldRect(&borderBetweenFields);
274
275 // it's the caller responsability to check this, if unsure - call
276 // GetFieldRect() instead
277 wxCHECK_MSG( !m_widthsAbs.IsEmpty(), rect,
278 _T("can't be called if we don't have the widths") );
279
280 for ( int i = 0; i <= n; i++ )
281 {
282 rect.width = m_widthsAbs[i];
283
284 if ( i < n )
285 rect.x += rect.width + borderBetweenFields;
286 }
287
288 return rect;
289 }
290
291 wxCoord wxStatusBarUniv::GetHeight() const
292 {
293 wxClientDC dc(wxConstCast(this, wxStatusBarUniv));
294 dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
295
296 return dc.GetCharHeight() + 2*GetBorderY();
297 }
298
299 wxSize wxStatusBarUniv::DoGetBestSize() const
300 {
301 return wxSize(100, GetHeight());
302 }
303
304 void wxStatusBarUniv::DoSetSize(int x, int y,
305 int width, int WXUNUSED(height),
306 int sizeFlags)
307 {
308 wxStatusBarBase::DoSetSize(x, y, width, GetHeight(), sizeFlags);
309 }
310
311 // ----------------------------------------------------------------------------
312 // misc
313 // ----------------------------------------------------------------------------
314
315 void wxStatusBarUniv::SetMinHeight(int WXUNUSED(height))
316 {
317 // nothing to do here, we don't support it - and why would we?
318 }
319
320 int wxStatusBarUniv::GetBorderX() const
321 {
322 return m_renderer->GetStatusBarBorders(NULL).x;
323 }
324
325 int wxStatusBarUniv::GetBorderY() const
326 {
327 return m_renderer->GetStatusBarBorders(NULL).y;
328 }
329
330 #endif // wxUSE_STATUSBAR