]> git.saurik.com Git - wxWidgets.git/blame - src/generic/statusbr.cpp
The standalone PyShell and PyCrust apps need to set the focus to the
[wxWidgets.git] / src / generic / statusbr.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
ed791986
VZ
2// Name: generic/statusbr.cpp
3// Purpose: wxStatusBarGeneric class implementation
c801d85f
KB
4// Author: Julian Smart
5// Modified by:
6// Created: 01/02/97
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart and Markus Holzem
ed791986 9// Licence: wxWindows license
c801d85f
KB
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
1e6feb95 23#if wxUSE_STATUSBAR
ed791986 24
c801d85f
KB
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
412e4edf 32#include "wx/statusbr.h"
c801d85f 33
84f68c21
VZ
34// we only have to do it here when we use wxStatusBarGeneric in addition to the
35// standard wxStatusBar class, if wxStatusBarGeneric is the same as
36// wxStatusBar, then the corresponding IMPLEMENT_DYNAMIC_CLASS is already in
37// common/statbar.cpp
38#if defined(__WXMAC__) || \
39 (defined(wxUSE_NATIVE_STATUSBAR) && wxUSE_NATIVE_STATUSBAR)
b64a8473 40 #include "wx/generic/statusbr.h"
c801d85f 41
b64a8473
VZ
42 IMPLEMENT_DYNAMIC_CLASS(wxStatusBarGeneric, wxWindow)
43#endif // wxUSE_NATIVE_STATUSBAR
ed791986 44
ed791986
VZ
45BEGIN_EVENT_TABLE(wxStatusBarGeneric, wxWindow)
46 EVT_PAINT(wxStatusBarGeneric::OnPaint)
390015c0
VZ
47 EVT_SIZE(wxStatusBarGeneric::OnSize)
48
ed791986 49 EVT_SYS_COLOUR_CHANGED(wxStatusBarGeneric::OnSysColourChanged)
c801d85f 50END_EVENT_TABLE()
c801d85f
KB
51
52// Default status border dimensions
53#define wxTHICK_LINE_BORDER 2
54#define wxTHICK_LINE_WIDTH 1
55
390015c0 56void wxStatusBarGeneric::Init()
c801d85f 57{
c801d85f
KB
58 m_borderX = wxTHICK_LINE_BORDER;
59 m_borderY = wxTHICK_LINE_BORDER;
60}
61
ed791986 62wxStatusBarGeneric::~wxStatusBarGeneric()
c801d85f 63{
390015c0
VZ
64 // VZ: what is this for? please comment...
65#ifdef __WXMSW__
66 SetFont(wxNullFont);
67#endif // MSW
c801d85f
KB
68}
69
ed791986 70bool wxStatusBarGeneric::Create(wxWindow *parent,
76880b87
RL
71 wxWindowID id,
72 long style,
73 const wxString& name)
c801d85f 74{
390015c0
VZ
75 if ( !wxWindow::Create(parent, id,
76 wxDefaultPosition, wxDefaultSize,
77 style | wxTAB_TRAVERSAL, name) )
78 return FALSE;
c801d85f 79
f90566f5
RR
80 // The status bar should have a themed background
81 SetThemeEnabled( TRUE );
82
c801d85f 83 // Don't wish this to be found as a child
7c74e7fe 84#ifndef __WXMAC__
c0ed460c 85 parent->GetChildren().DeleteObject(this);
7c74e7fe 86#endif
c801d85f
KB
87 InitColours();
88
89 SetFont(m_defaultStatusBarFont);
90
71e03035
VZ
91 // Set the height according to the font and the border size
92 wxClientDC dc(this);
93 dc.SetFont(GetFont());
94
95 wxCoord y;
96 dc.GetTextExtent(_T("X"), NULL, &y );
97
98 int height = (int)( (11*y)/10 + 2*GetBorderY());
99
100 SetSize(-1, -1, -1, height);
101
390015c0 102 return TRUE;
c801d85f
KB
103}
104
cc56206f 105void wxStatusBarGeneric::SetFieldsCount(int number, const int *widths)
c801d85f 106{
390015c0 107 wxASSERT_MSG( number >= 0, _T("negative number of fields in wxStatusBar?") );
76880b87 108
893f25f2
JS
109 int i;
110 for(i = m_nFields; i < number; ++i)
76880b87
RL
111 m_statusStrings.Add( wxEmptyString );
112
893f25f2 113 for (i = m_nFields - 1; i >= number; --i)
390015c0 114 m_statusStrings.RemoveAt(i);
76880b87
RL
115
116 m_nFields = number;
117
118 wxASSERT_MSG( m_nFields == (int)m_statusStrings.GetCount(),
119 _T("This really should never happen, can we do away with m_nFields here?") );
c801d85f 120
633d67bb 121 SetStatusWidths(number, widths);
c801d85f
KB
122}
123
ed791986 124void wxStatusBarGeneric::SetStatusText(const wxString& text, int number)
c801d85f 125{
633d67bb
VZ
126 wxCHECK_RET( (number >= 0) && (number < m_nFields),
127 _T("invalid status bar field index") );
c801d85f 128
633d67bb 129 m_statusStrings[number] = text;
c801d85f 130
f8a4fa4c
VZ
131 wxRect rect;
132 GetFieldRect(number, rect);
e715f4e7 133
f90566f5 134 Refresh( TRUE, &rect );
c801d85f
KB
135}
136
ed791986 137wxString wxStatusBarGeneric::GetStatusText(int n) const
c801d85f 138{
ed791986
VZ
139 wxCHECK_MSG( (n >= 0) && (n < m_nFields), wxEmptyString,
140 _T("invalid status bar field index") );
141
c801d85f
KB
142 return m_statusStrings[n];
143}
144
ed791986 145void wxStatusBarGeneric::SetStatusWidths(int n, const int widths_field[])
c801d85f 146{
633d67bb
VZ
147 // only set status widths, when n == number of statuswindows
148 wxCHECK_RET( n == m_nFields, _T("status bar field count mismatch") );
149
150 // delete the old widths in any case - this function may be used to reset
151 // the widths to the default (all equal)
1f361cdd
MB
152 // MBN: this is incompatible with at least wxMSW and wxMAC and not
153 // documented, but let's keep it for now
154 ReinitWidths();
633d67bb 155
390015c0
VZ
156 // forget the old cached pixel widths
157 m_widthsAbs.Empty();
158
633d67bb
VZ
159 if ( !widths_field )
160 {
161 // not an error, see the comment above
f8a4fa4c 162 Refresh();
633d67bb
VZ
163 return;
164 }
165
1f361cdd 166 wxStatusBarBase::SetStatusWidths(n, widths_field);
c801d85f
KB
167}
168
ed791986 169void wxStatusBarGeneric::OnPaint(wxPaintEvent& WXUNUSED(event) )
c801d85f
KB
170{
171 wxPaintDC dc(this);
172
5b3ed311 173
c801d85f 174 int i;
c0ed460c
JS
175 if ( GetFont().Ok() )
176 dc.SetFont(GetFont());
c801d85f
KB
177 dc.SetBackgroundMode(wxTRANSPARENT);
178
28be2e8a 179#ifdef __WXPM__
b34590eb
DW
180 wxColour vColor;
181
e715f4e7 182 vColor = wxSystemSettings::GetColour(wxSYS_COLOUR_MENUBAR);
b34590eb 183 ::WinFillRect(dc.m_hPS, &dc.m_vRclPaint, vColor.GetPixel());
28be2e8a
DW
184#endif
185
c801d85f 186 for ( i = 0; i < m_nFields; i ++ )
f51f94ea 187 DrawField(dc, i);
e97f20a0 188
390015c0 189 // VZ: again, what is this for?
28be2e8a
DW
190#ifdef __WXMSW__
191 dc.SetFont(wxNullFont);
192#endif // MSW
c801d85f
KB
193}
194
ed791986 195void wxStatusBarGeneric::DrawFieldText(wxDC& dc, int i)
c801d85f
KB
196{
197 int leftMargin = 2;
198
16e93305 199 wxRect rect;
c801d85f
KB
200 GetFieldRect(i, rect);
201
202 wxString text(GetStatusText(i));
203
204 long x, y;
205
206 dc.GetTextExtent(text, &x, &y);
207
208 int xpos = rect.x + leftMargin;
209 int ypos = (int) (((rect.height - y) / 2 ) + rect.y + 0.5) ;
ed791986 210
7c74e7fe 211#if defined( __WXGTK__ ) || defined(__WXMAC__)
92976ab6
RR
212 xpos++;
213 ypos++;
214#endif
c801d85f
KB
215
216 dc.SetClippingRegion(rect.x, rect.y, rect.width, rect.height);
217
218 dc.DrawText(text, xpos, ypos);
219
220 dc.DestroyClippingRegion();
221}
222
ed791986 223void wxStatusBarGeneric::DrawField(wxDC& dc, int i)
c801d85f 224{
16e93305 225 wxRect rect;
c801d85f
KB
226 GetFieldRect(i, rect);
227
228 // Draw border
229 // Have grey background, plus 3-d border -
230 // One black rectangle.
231 // Inside this, left and top sides - dark grey. Bottom and right -
232 // white.
233
f51f94ea 234 dc.SetPen(m_hilightPen);
c801d85f 235
b34590eb
DW
236#ifndef __WXPM__
237
c801d85f
KB
238 // Right and bottom white lines
239 dc.DrawLine(rect.x + rect.width, rect.y,
240 rect.x + rect.width, rect.y + rect.height);
241 dc.DrawLine(rect.x + rect.width, rect.y + rect.height,
f51f94ea 242 rect.x, rect.y + rect.height);
c801d85f 243
f51f94ea 244 dc.SetPen(m_mediumShadowPen);
c801d85f
KB
245
246 // Left and top grey lines
247 dc.DrawLine(rect.x, rect.y + rect.height,
f51f94ea 248 rect.x, rect.y);
c801d85f 249 dc.DrawLine(rect.x, rect.y,
f51f94ea 250 rect.x + rect.width, rect.y);
b34590eb 251#else
e715f4e7
DW
252
253 dc.DrawLine(rect.x + rect.width, rect.height + 2,
254 rect.x, rect.height + 2);
702c190d 255 dc.DrawLine(rect.x + rect.width, rect.y,
e715f4e7
DW
256 rect.x + rect.width, rect.y + rect.height);
257
b34590eb 258 dc.SetPen(m_mediumShadowPen);
e715f4e7
DW
259 dc.DrawLine(rect.x, rect.y,
260 rect.x + rect.width, rect.y);
261 dc.DrawLine(rect.x, rect.y + rect.height,
262 rect.x, rect.y);
b34590eb
DW
263
264#endif
c801d85f 265
f51f94ea 266 DrawFieldText(dc, i);
c801d85f
KB
267}
268
269 // Get the position and size of the field's internal bounding rectangle
ed791986 270bool wxStatusBarGeneric::GetFieldRect(int n, wxRect& rect) const
c801d85f 271{
390015c0
VZ
272 wxCHECK_MSG( (n >= 0) && (n < m_nFields), FALSE,
273 _T("invalid status bar field index") );
c801d85f 274
390015c0
VZ
275 // FIXME: workarounds for OS/2 bugs have nothing to do here (VZ)
276 int width, height;
28be2e8a 277#ifdef __WXPM__
390015c0 278 GetSize(&width, &height);
28be2e8a 279#else
390015c0 280 GetClientSize(&width, &height);
28be2e8a 281#endif
c801d85f 282
390015c0
VZ
283 // we cache m_widthsAbs between calls normally but it's cleared when the
284 // status widths change so recompute it if needed
285 if ( m_widthsAbs.IsEmpty() )
c801d85f 286 {
390015c0
VZ
287 wxConstCast(this, wxStatusBarGeneric)->
288 m_widthsAbs = CalculateAbsWidths(width);
c801d85f 289 }
c801d85f 290
390015c0
VZ
291 rect.x = 0;
292 for ( int i = 0; i < n; i++ )
293 {
294 rect.x += m_widthsAbs[i];
c801d85f 295 }
c801d85f 296
390015c0
VZ
297 rect.x += m_borderX;
298 rect.y = m_borderY;
c801d85f 299
390015c0
VZ
300 rect.width = m_widthsAbs[n] - 2*m_borderX;
301 rect.height = height - 2*m_borderY;
c801d85f 302
f51f94ea 303 return TRUE;
c801d85f
KB
304}
305
306// Initialize colours
ed791986 307void wxStatusBarGeneric::InitColours()
c801d85f
KB
308{
309 // Shadow colours
5b3ed311 310#if defined(__WIN95__)
a756f210 311 wxColour mediumShadowColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW));
c801d85f
KB
312 m_mediumShadowPen = wxPen(mediumShadowColour, 1, wxSOLID);
313
a756f210 314 wxColour hilightColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DHILIGHT));
c801d85f 315 m_hilightPen = wxPen(hilightColour, 1, wxSOLID);
b34590eb 316#elif defined(__WXPM__)
e715f4e7 317 m_mediumShadowPen = wxPen(wxColour(127, 127, 127), 1, wxSOLID);
b34590eb 318 m_hilightPen = wxPen("WHITE", 1, wxSOLID);
dd7d1435
DW
319
320 wxColour vColour;
321
5e5390dd 322 vColour.Set(wxString("LIGHT GREY"));
dd7d1435 323 SetBackgroundColour(vColour);
5e5390dd 324 vColour.Set(wxString("BLACK"));
dd7d1435
DW
325 SetForegroundColour(vColour);
326 m_defaultStatusBarFont = *wxSMALL_FONT;
c801d85f
KB
327#else
328 m_mediumShadowPen = wxPen("GREY", 1, wxSOLID);
329 m_hilightPen = wxPen("WHITE", 1, wxSOLID);
330#endif
331
dd7d1435 332#ifndef __WXPM__
a756f210
VS
333 m_defaultStatusBarFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
334 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
dd7d1435 335#endif
c801d85f
KB
336}
337
338// Responds to colour changes, and passes event on to children.
ed791986 339void wxStatusBarGeneric::OnSysColourChanged(wxSysColourChangedEvent& event)
c801d85f
KB
340{
341 InitColours();
342 Refresh();
343
344 // Propagate the event to the non-top-level children
345 wxWindow::OnSysColourChanged(event);
346}
347
ed791986
VZ
348void wxStatusBarGeneric::SetMinHeight(int height)
349{
350 // check that this min height is not less than minimal height for the
351 // current font
352 wxClientDC dc(this);
353 wxCoord y;
354 dc.GetTextExtent( _T("X"), NULL, &y );
355
356 if ( height > (11*y)/10 )
357 {
358 SetSize(-1, -1, -1, height + 2*m_borderY);
359 }
360}
361
390015c0
VZ
362void wxStatusBarGeneric::OnSize(wxSizeEvent& event)
363{
364 // have to recompute the widths in pixels
365 m_widthsAbs.Empty();
366
367 event.Skip();
368}
369
1e6feb95 370#endif // wxUSE_STATUSBAR
76880b87 371