1 /////////////////////////////////////////////////////////////////////////////
2 // Name: univ/statusbr.cpp
3 // Purpose: wxStatusBar implementation
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "univstatusbr.h"
24 #include "wx/wxprec.h"
33 #include "wx/settings.h"
34 #include "wx/dcclient.h"
37 #include "wx/statusbr.h"
38 #include "wx/toplevel.h"
40 #include "wx/univ/renderer.h"
42 // ============================================================================
44 // ============================================================================
46 BEGIN_EVENT_TABLE(wxStatusBarUniv
, wxStatusBarBase
)
47 EVT_SIZE(wxStatusBarUniv::OnSize
)
49 WX_EVENT_TABLE_INPUT_CONSUMER(wxStatusBarUniv
)
52 WX_FORWARD_TO_INPUT_CONSUMER(wxStatusBarUniv
)
54 // ----------------------------------------------------------------------------
56 // ----------------------------------------------------------------------------
58 void wxStatusBarUniv::Init()
62 bool wxStatusBarUniv::Create(wxWindow
*parent
,
67 if ( !wxWindow::Create(parent
, id
,
68 wxDefaultPosition
, wxDefaultSize
,
76 CreateInputHandler(wxINP_HANDLER_STATUSBAR
);
78 SetSize(DoGetBestSize());
83 // ----------------------------------------------------------------------------
85 // ----------------------------------------------------------------------------
87 wxRect
wxStatusBarUniv::GetTotalFieldRect(wxCoord
*borderBetweenFields
)
89 wxRect rect
= GetClientRect();
91 // no, don't do this - the borders are meant to be inside this rect
92 // wxSize sizeBorders =
93 m_renderer
->GetStatusBarBorders(borderBetweenFields
);
94 //rect.Deflate(sizeBorders.x, sizeBorders.y);
96 // recalc the field widths if needed
97 if ( m_widthsAbs
.IsEmpty() )
99 // the total width for the fields doesn't include the borders between
101 m_widthsAbs
= CalculateAbsWidths(rect
.width
-
102 *borderBetweenFields
*(m_nFields
- 1));
108 void wxStatusBarUniv::DoDraw(wxControlRenderer
*renderer
)
110 // get the fields rect
111 wxCoord borderBetweenFields
;
112 wxRect rect
= GetTotalFieldRect(&borderBetweenFields
);
115 wxDC
& dc
= renderer
->GetDC();
116 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
118 // do draw the fields
119 int flags
= IsEnabled() ? 0 : wxCONTROL_DISABLED
;
120 for ( int n
= 0; n
< m_nFields
; n
++ )
122 rect
.width
= m_widthsAbs
[n
];
124 if ( IsExposed(rect
) )
126 wxTopLevelWindow
*parentTLW
= wxDynamicCast(GetParent(), wxTopLevelWindow
);
128 // the size grip may be drawn only on the last field and only if we
129 // have the corresponding style and even then only if we really can
131 if ( n
== m_nFields
- 1 &&
132 HasFlag(wxST_SIZEGRIP
) &&
133 GetParent()->HasFlag(wxRESIZE_BORDER
) &&
134 parentTLW
&& !parentTLW
->IsMaximized() )
136 // NB: we use wxCONTROL_ISDEFAULT for this because it doesn't
137 // have any meaning for the status bar otherwise anyhow
138 // (it's still ugly, of course, but there are too few flags
139 // to squander them for things like this)
140 flags
|= wxCONTROL_ISDEFAULT
;
143 m_renderer
->DrawStatusField(dc
, rect
, m_statusText
[n
], flags
);
146 rect
.x
+= rect
.width
+ borderBetweenFields
;
150 void wxStatusBarUniv::RefreshField(int i
)
153 if ( GetFieldRect(i
, rect
) )
159 // ----------------------------------------------------------------------------
161 // ----------------------------------------------------------------------------
163 void wxStatusBarUniv::SetStatusText(const wxString
& text
, int number
)
165 wxCHECK_RET( number
>= 0 && number
< m_nFields
,
166 _T("invalid status bar field index in SetStatusText()") );
168 if ( text
== m_statusText
[number
] )
174 m_statusText
[number
] = text
;
176 RefreshField(number
);
179 wxString
wxStatusBarUniv::GetStatusText(int number
) const
181 wxCHECK_MSG( number
>= 0 && number
< m_nFields
, _T(""),
182 _T("invalid status bar field index") );
184 return m_statusText
[number
];
187 // ----------------------------------------------------------------------------
188 // fields count/widths
189 // ----------------------------------------------------------------------------
191 void wxStatusBarUniv::SetFieldsCount(int number
, const int *widths
)
193 m_statusText
.SetCount(number
);
194 wxStatusBarBase::SetFieldsCount(number
, widths
);
198 void wxStatusBarUniv::SetStatusWidths(int n
, const int widths
[])
200 wxStatusBarBase::SetStatusWidths(n
, widths
);
205 // ----------------------------------------------------------------------------
207 // ----------------------------------------------------------------------------
209 void wxStatusBarUniv::OnSize(wxSizeEvent
& event
)
211 // we don't need to refresh the fields whose width didn't change, so find
212 // the first field whose width did change and refresh starting from it
214 if ( m_statusWidths
)
216 for ( field
= 0; field
< m_nFields
; field
++ )
218 if ( m_statusWidths
[field
] < 0 )
225 else // all fields have the same width
227 // hence all fields widths have changed
231 if ( field
< m_nFields
)
233 // call this before invalidating the old widths as we want to use them,
235 wxRect rect
= DoGetFieldRect(field
);
237 // invalidate the widths, we'll have to recalc them
240 // refresh everything after the first invalid field
242 rect
.SetRight(event
.GetSize().x
);
243 rect
.height
= event
.GetSize().y
;
250 bool wxStatusBarUniv::GetFieldRect(int n
, wxRect
& rect
) const
252 wxCHECK_MSG( n
>= 0 && n
< m_nFields
, FALSE
,
253 _T("invalid field index in GetFieldRect()") );
255 // this is a fix for a bug exhibited by the statbar sample: if
256 // GetFieldRect() is called from the derived class OnSize() handler, then
257 // our geometry info is wrong as our OnSize() didn't invalidate m_widthsAbs
258 // yet - so recalc it just in case
259 wxConstCast(this, wxStatusBarUniv
)->m_widthsAbs
.Empty();
261 rect
= DoGetFieldRect(n
);
266 wxRect
wxStatusBarUniv::DoGetFieldRect(int n
) const
268 wxStatusBarUniv
*self
= wxConstCast(this, wxStatusBarUniv
);
270 wxCoord borderBetweenFields
;
271 wxRect rect
= self
->GetTotalFieldRect(&borderBetweenFields
);
273 // it's the caller responsability to check this, if unsure - call
274 // GetFieldRect() instead
275 wxCHECK_MSG( !m_widthsAbs
.IsEmpty(), rect
,
276 _T("can't be called if we don't have the widths") );
278 for ( int i
= 0; i
<= n
; i
++ )
280 rect
.width
= m_widthsAbs
[i
];
283 rect
.x
+= rect
.width
+ borderBetweenFields
;
289 wxCoord
wxStatusBarUniv::GetHeight() const
291 wxClientDC
dc(wxConstCast(this, wxStatusBarUniv
));
292 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
294 return dc
.GetCharHeight() + 2*GetBorderY();
297 wxSize
wxStatusBarUniv::DoGetBestSize() const
299 return wxSize(100, GetHeight());
302 void wxStatusBarUniv::DoSetSize(int x
, int y
,
303 int width
, int WXUNUSED(height
),
306 wxStatusBarBase::DoSetSize(x
, y
, width
, GetHeight(), sizeFlags
);
309 // ----------------------------------------------------------------------------
311 // ----------------------------------------------------------------------------
313 void wxStatusBarUniv::SetMinHeight(int WXUNUSED(height
))
315 // nothing to do here, we don't support it - and why would we?
318 int wxStatusBarUniv::GetBorderX() const
320 return m_renderer
->GetStatusBarBorders(NULL
).x
;
323 int wxStatusBarUniv::GetBorderY() const
325 return m_renderer
->GetStatusBarBorders(NULL
).y
;
328 #endif // wxUSE_STATUSBAR