1. added wxStatusBarUniv
[wxWidgets.git] / src / generic / statusbr.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: generic/statusbr.cpp
3 // Purpose: wxStatusBarGeneric class implementation
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 01/02/97
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "statusbr.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #if wxUSE_STATUSBAR
24
25 #ifndef WX_PRECOMP
26 #include "wx/setup.h"
27 #include "wx/frame.h"
28 #include "wx/settings.h"
29 #include "wx/dcclient.h"
30 #endif
31
32 #include "wx/statusbr.h"
33
34 // with wxUSE_NATIVE_STATUSBAR it is not included from wx/statusbr.h
35 #include "wx/generic/statusbr.h"
36
37 IMPLEMENT_DYNAMIC_CLASS(wxStatusBarGeneric, wxWindow)
38
39 BEGIN_EVENT_TABLE(wxStatusBarGeneric, wxWindow)
40 EVT_PAINT(wxStatusBarGeneric::OnPaint)
41 EVT_SYS_COLOUR_CHANGED(wxStatusBarGeneric::OnSysColourChanged)
42 END_EVENT_TABLE()
43
44 // Default status border dimensions
45 #define wxTHICK_LINE_BORDER 2
46 #define wxTHICK_LINE_WIDTH 1
47
48 wxStatusBarGeneric::wxStatusBarGeneric()
49 {
50 m_statusWidths = (int *) NULL;
51 m_statusStrings = (wxString *) NULL;
52 m_nFields = 0;
53 m_borderX = wxTHICK_LINE_BORDER;
54 m_borderY = wxTHICK_LINE_BORDER;
55 }
56
57 wxStatusBarGeneric::~wxStatusBarGeneric()
58 {
59 # ifdef __WXMSW__
60 SetFont(wxNullFont);
61 # endif // MSW
62
63 if ( m_statusStrings )
64 delete[] m_statusStrings;
65 }
66
67 bool wxStatusBarGeneric::Create(wxWindow *parent,
68 wxWindowID id,
69 long style,
70 const wxString& name)
71 {
72 m_statusWidths = (int *) NULL;
73 m_statusStrings = (wxString *) NULL;
74 m_nFields = 0;
75 m_borderX = wxTHICK_LINE_BORDER;
76 m_borderY = wxTHICK_LINE_BORDER;
77
78 bool success = wxWindow::Create(parent, id,
79 wxDefaultPosition, wxDefaultSize,
80 style | wxTAB_TRAVERSAL, name);
81
82 // Don't wish this to be found as a child
83 #ifndef __WXMAC__
84 parent->GetChildren().DeleteObject(this);
85 #endif
86 InitColours();
87
88 SetFont(m_defaultStatusBarFont);
89
90 // Set the height according to the font and the border size
91 wxClientDC dc(this);
92 dc.SetFont(GetFont());
93
94 wxCoord y;
95 dc.GetTextExtent(_T("X"), NULL, &y );
96
97 int height = (int)( (11*y)/10 + 2*GetBorderY());
98
99 SetSize(-1, -1, -1, height);
100
101 return success;
102 }
103
104 void wxStatusBarGeneric::SetFieldsCount(int number, const int *widths)
105 {
106 if ( number != m_nFields )
107 {
108 m_nFields = number;
109
110 delete[] m_statusStrings;
111 m_statusStrings = new wxString[number];
112 }
113
114 SetStatusWidths(number, widths);
115 }
116
117 void wxStatusBarGeneric::SetStatusText(const wxString& text, int number)
118 {
119 wxCHECK_RET( (number >= 0) && (number < m_nFields),
120 _T("invalid status bar field index") );
121
122 m_statusStrings[number] = text;
123
124 Refresh();
125 }
126
127 wxString wxStatusBarGeneric::GetStatusText(int n) const
128 {
129 wxCHECK_MSG( (n >= 0) && (n < m_nFields), wxEmptyString,
130 _T("invalid status bar field index") );
131
132 return m_statusStrings[n];
133 }
134
135 void wxStatusBarGeneric::SetStatusWidths(int n, const int widths_field[])
136 {
137 // only set status widths, when n == number of statuswindows
138 wxCHECK_RET( n == m_nFields, _T("status bar field count mismatch") );
139
140 // delete the old widths in any case - this function may be used to reset
141 // the widths to the default (all equal)
142 delete [] m_statusWidths;
143
144 if ( !widths_field )
145 {
146 // not an error, see the comment above
147 m_statusWidths = (int *)NULL;
148
149 return;
150 }
151
152 int i;
153
154 // VZ: this doesn't do anything as is_variable is unused later
155 #if 0
156 // when one window (minimum) is variable (width <= 0)
157 bool is_variable = FALSE;
158 for (i = 0; i < m_nFields; i++)
159 {
160 if (widths_field[i] <= 0)
161 is_variable = TRUE;
162 }
163 #endif // 0
164
165 // set widths
166 m_statusWidths = new int[n];
167 for (i = 0; i < m_nFields; i++)
168 {
169 m_statusWidths[i] = widths_field[i];
170 }
171 }
172
173 void wxStatusBarGeneric::OnPaint(wxPaintEvent& WXUNUSED(event) )
174 {
175 wxPaintDC dc(this);
176
177
178 int i;
179 if ( GetFont().Ok() )
180 dc.SetFont(GetFont());
181 dc.SetBackgroundMode(wxTRANSPARENT);
182
183 #ifdef __WXPM__
184 wxColour vColor;
185
186 vColor.InitFromName("GREY");
187 ::WinFillRect(dc.m_hPS, &dc.m_vRclPaint, vColor.GetPixel());
188 #endif
189
190 for ( i = 0; i < m_nFields; i ++ )
191 DrawField(dc, i);
192
193 #ifdef __WXMSW__
194 dc.SetFont(wxNullFont);
195 #endif // MSW
196 }
197
198 void wxStatusBarGeneric::DrawFieldText(wxDC& dc, int i)
199 {
200 int leftMargin = 2;
201
202 wxRect rect;
203 GetFieldRect(i, rect);
204
205 wxString text(GetStatusText(i));
206
207 long x, y;
208
209 dc.GetTextExtent(text, &x, &y);
210
211 int xpos = rect.x + leftMargin;
212 int ypos = (int) (((rect.height - y) / 2 ) + rect.y + 0.5) ;
213
214 #if defined( __WXGTK__ ) || defined(__WXMAC__)
215 xpos++;
216 ypos++;
217 #endif
218
219 dc.SetClippingRegion(rect.x, rect.y, rect.width, rect.height);
220
221 dc.DrawText(text, xpos, ypos);
222
223 dc.DestroyClippingRegion();
224 }
225
226 void wxStatusBarGeneric::DrawField(wxDC& dc, int i)
227 {
228 wxRect rect;
229 GetFieldRect(i, rect);
230
231 // Draw border
232 // Have grey background, plus 3-d border -
233 // One black rectangle.
234 // Inside this, left and top sides - dark grey. Bottom and right -
235 // white.
236
237 dc.SetPen(m_hilightPen);
238
239 #ifndef __WXPM__
240
241 // Right and bottom white lines
242 dc.DrawLine(rect.x + rect.width, rect.y,
243 rect.x + rect.width, rect.y + rect.height);
244 dc.DrawLine(rect.x + rect.width, rect.y + rect.height,
245 rect.x, rect.y + rect.height);
246
247 dc.SetPen(m_mediumShadowPen);
248
249 // Left and top grey lines
250 dc.DrawLine(rect.x, rect.y + rect.height,
251 rect.x, rect.y);
252 dc.DrawLine(rect.x, rect.y,
253 rect.x + rect.width, rect.y);
254 #else
255 // Right
256 dc.DrawLine(rect.x + rect.width, rect.y,
257 rect.x + rect.width, rect.y + rect.height + 2);
258 dc.SetPen(m_mediumShadowPen);
259 dc.DrawLine(rect.x + rect.width + 1, rect.y,
260 rect.x + rect.width + 1, rect.y + rect.height + 2);
261 dc.DrawLine(rect.x + rect.width + 2, rect.y,
262 rect.x + rect.width + 2, rect.y + rect.height + 2);
263 // Top
264 dc.DrawLine(rect.x + rect.width + 2, rect.y,
265 rect.x - 2, rect.y);
266 dc.DrawLine(rect.x + rect.width + 1, rect.y - 1,
267 rect.x - 2, rect.y - 1);
268 dc.SetPen(m_hilightPen);
269 dc.DrawLine(rect.x + rect.width, rect.y - 2,
270 rect.x - 2, rect.y - 2);
271
272 #endif
273
274 DrawFieldText(dc, i);
275 }
276
277 // Get the position and size of the field's internal bounding rectangle
278 bool wxStatusBarGeneric::GetFieldRect(int n, wxRect& rect) const
279 {
280 wxCHECK_MSG( (n >= 0) && (n < m_nFields), FALSE,
281 _T("invalid status bar field index") );
282
283 int width, height;
284 #ifdef __WXPM__
285 GetSize(&width, &height);
286 #else
287 GetClientSize(&width, &height);
288 #endif
289
290 int i;
291 int sum_of_nonvar = 0;
292 int num_of_var = 0;
293 bool do_same_width = FALSE;
294
295 int fieldWidth = 0;
296 int fieldPosition = 0;
297
298 if (m_statusWidths)
299 {
300 // if sum(not variable Windows) > c_width - (20 points per variable_window)
301 // then do_same_width = TRUE;
302 for (i = 0; i < m_nFields; i++)
303 {
304 if (m_statusWidths[i] > 0) sum_of_nonvar += m_statusWidths[i];
305 else num_of_var++;
306 }
307 if (sum_of_nonvar > (width - 20*num_of_var)) do_same_width = TRUE;
308 }
309 else do_same_width = TRUE;
310 if (do_same_width)
311 {
312 for (i = 0; i < m_nFields; i++)
313 {
314 fieldWidth = (int)(width/m_nFields);
315 fieldPosition = i*fieldWidth;
316 if ( i == n )
317 break;
318 }
319 }
320 else // no_same_width
321 {
322 int *tempwidth = new int[m_nFields];
323 int temppos = 0;
324 for (i = 0; i < m_nFields; i++)
325 {
326 if (m_statusWidths[i] > 0) tempwidth[i] = m_statusWidths[i];
327 else tempwidth[i] = (width - sum_of_nonvar) / num_of_var;
328 }
329 for (i = 0; i < m_nFields; i++)
330 {
331 fieldWidth = tempwidth[i];
332 fieldPosition = temppos;
333
334 temppos += tempwidth[i];
335
336 if ( i == n )
337 break;
338 }
339 delete [] tempwidth;
340 }
341
342 rect.x = fieldPosition + wxTHICK_LINE_BORDER;
343 rect.y = wxTHICK_LINE_BORDER;
344
345 rect.width = fieldWidth - 2 * wxTHICK_LINE_BORDER ;
346 rect.height = height - 2 * wxTHICK_LINE_BORDER ;
347
348 return TRUE;
349 }
350
351 // Initialize colours
352 void wxStatusBarGeneric::InitColours()
353 {
354 // Shadow colours
355 #if defined(__WIN95__)
356 wxColour mediumShadowColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW));
357 m_mediumShadowPen = wxPen(mediumShadowColour, 1, wxSOLID);
358
359 wxColour hilightColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHILIGHT));
360 m_hilightPen = wxPen(hilightColour, 1, wxSOLID);
361 #elif defined(__WXPM__)
362 m_mediumShadowPen = wxPen("LIGHT GREY", 1, wxSOLID);
363 m_hilightPen = wxPen("WHITE", 1, wxSOLID);
364 #else
365 m_mediumShadowPen = wxPen("GREY", 1, wxSOLID);
366 m_hilightPen = wxPen("WHITE", 1, wxSOLID);
367 #endif
368
369 m_defaultStatusBarFont = wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT);
370 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
371 }
372
373 // Responds to colour changes, and passes event on to children.
374 void wxStatusBarGeneric::OnSysColourChanged(wxSysColourChangedEvent& event)
375 {
376 InitColours();
377 Refresh();
378
379 // Propagate the event to the non-top-level children
380 wxWindow::OnSysColourChanged(event);
381 }
382
383 void wxStatusBarGeneric::SetMinHeight(int height)
384 {
385 // check that this min height is not less than minimal height for the
386 // current font
387 wxClientDC dc(this);
388 wxCoord y;
389 dc.GetTextExtent( _T("X"), NULL, &y );
390
391 if ( height > (11*y)/10 )
392 {
393 SetSize(-1, -1, -1, height + 2*m_borderY);
394 }
395 }
396
397 #endif // wxUSE_STATUSBAR