1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/univ/statusbr.cpp
3 // Purpose: wxStatusBar implementation
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 #include "wx/wxprec.h"
28 #include "wx/statusbr.h"
31 #include "wx/settings.h"
32 #include "wx/dcclient.h"
33 #include "wx/toplevel.h"
36 #include "wx/univ/renderer.h"
38 // ============================================================================
40 // ============================================================================
42 BEGIN_EVENT_TABLE(wxStatusBarUniv
, wxStatusBarBase
)
43 EVT_SIZE(wxStatusBarUniv::OnSize
)
45 WX_EVENT_TABLE_INPUT_CONSUMER(wxStatusBarUniv
)
48 WX_FORWARD_TO_INPUT_CONSUMER(wxStatusBarUniv
)
50 // ----------------------------------------------------------------------------
52 // ----------------------------------------------------------------------------
54 void wxStatusBarUniv::Init()
58 bool wxStatusBarUniv::Create(wxWindow
*parent
,
63 if ( !wxWindow::Create(parent
, id
,
64 wxDefaultPosition
, wxDefaultSize
,
72 CreateInputHandler(wxINP_HANDLER_STATUSBAR
);
74 SetSize(DoGetBestSize());
79 // ----------------------------------------------------------------------------
81 // ----------------------------------------------------------------------------
83 wxRect
wxStatusBarUniv::GetTotalFieldRect(wxCoord
*borderBetweenFields
)
85 wxRect rect
= GetClientRect();
87 // no, don't do this - the borders are meant to be inside this rect
88 // wxSize sizeBorders =
89 if ( borderBetweenFields
)
90 *borderBetweenFields
= m_renderer
->GetStatusBarBorderBetweenFields();
91 //rect.Deflate(sizeBorders.x, sizeBorders.y);
93 // recalc the field widths if needed
94 if ( m_widthsAbs
.IsEmpty() )
96 // the total width for the fields doesn't include the borders between
98 m_widthsAbs
= CalculateAbsWidths(rect
.width
-
99 *borderBetweenFields
*(m_panes
.GetCount() - 1));
105 void wxStatusBarUniv::DoDraw(wxControlRenderer
*renderer
)
107 // get the fields rect
108 wxCoord borderBetweenFields
;
109 wxRect rect
= GetTotalFieldRect(&borderBetweenFields
);
112 wxDC
& dc
= renderer
->GetDC();
113 dc
.SetFont(GetFont());
114 dc
.SetTextForeground(GetForegroundColour());
116 // do draw the fields
117 int flags
= IsEnabled() ? 0 : (int)wxCONTROL_DISABLED
;
118 for ( int n
= 0; n
< (int)m_panes
.GetCount(); n
++ )
120 rect
.width
= m_widthsAbs
[n
];
122 if ( IsExposed(rect
) )
124 wxTopLevelWindow
*parentTLW
= wxDynamicCast(GetParent(), wxTopLevelWindow
);
126 // the size grip may be drawn only on the last field and only if we
127 // have the corresponding style and even then only if we really can
129 if ( n
== (int)m_panes
.GetCount() - 1 &&
130 HasFlag(wxST_SIZEGRIP
) &&
131 GetParent()->HasFlag(wxRESIZE_BORDER
) &&
132 parentTLW
&& !parentTLW
->IsMaximized() )
134 flags
|= wxCONTROL_SIZEGRIP
;
137 m_renderer
->DrawStatusField(dc
, rect
, m_statusText
[n
], flags
, m_panes
[n
].nStyle
);
140 rect
.x
+= rect
.width
+ borderBetweenFields
;
144 void wxStatusBarUniv::RefreshField(int i
)
147 if ( GetFieldRect(i
, rect
) )
153 // ----------------------------------------------------------------------------
155 // ----------------------------------------------------------------------------
157 void wxStatusBarUniv::SetStatusText(const wxString
& text
, int number
)
159 wxCHECK_RET( number
>= 0 && (size_t)number
< m_panes
.GetCount(),
160 _T("invalid status bar field index in SetStatusText()") );
162 if ( text
== m_statusText
[number
] )
168 m_statusText
[number
] = text
;
170 RefreshField(number
);
173 wxString
wxStatusBarUniv::GetStatusText(int number
) const
175 wxCHECK_MSG( number
>= 0 && (size_t)number
< m_panes
.GetCount(), wxEmptyString
,
176 _T("invalid status bar field index") );
178 return m_statusText
[number
];
181 // ----------------------------------------------------------------------------
182 // fields count/widths
183 // ----------------------------------------------------------------------------
185 void wxStatusBarUniv::SetFieldsCount(int number
, const int *widths
)
187 m_statusText
.SetCount(number
);
188 wxStatusBarBase::SetFieldsCount(number
, widths
);
193 void wxStatusBarUniv::SetStatusWidths(int n
, const int widths
[])
195 wxStatusBarBase::SetStatusWidths(n
, widths
);
200 // ----------------------------------------------------------------------------
202 // ----------------------------------------------------------------------------
204 void wxStatusBarUniv::OnSize(wxSizeEvent
& event
)
206 // we don't need to refresh the fields whose width didn't change, so find
207 // the first field whose width did change and refresh starting from it
209 if ( m_bSameWidthForAllPanes
)
211 // hence all fields widths have changed
216 for ( field
= 0; field
< m_panes
.GetCount(); field
++ )
218 if ( m_panes
[field
].nWidth
< 0 )
226 if ( field
< m_panes
.GetCount() )
228 // call this before invalidating the old widths as we want to use them,
230 wxRect rect
= DoGetFieldRect(field
);
232 // invalidate the widths, we'll have to recalc them
235 // refresh everything after the first invalid field
237 rect
.SetRight(event
.GetSize().x
);
238 rect
.height
= event
.GetSize().y
;
245 bool wxStatusBarUniv::GetFieldRect(int n
, wxRect
& rect
) const
247 wxCHECK_MSG( n
>= 0 && (size_t)n
< m_panes
.GetCount(), false,
248 _T("invalid field index in GetFieldRect()") );
250 // this is a fix for a bug exhibited by the statbar sample: if
251 // GetFieldRect() is called from the derived class OnSize() handler, then
252 // our geometry info is wrong as our OnSize() didn't invalidate m_widthsAbs
253 // yet - so recalc it just in case
254 wxConstCast(this, wxStatusBarUniv
)->m_widthsAbs
.Empty();
256 rect
= DoGetFieldRect(n
);
261 wxRect
wxStatusBarUniv::DoGetFieldRect(int n
) const
263 wxStatusBarUniv
*self
= wxConstCast(this, wxStatusBarUniv
);
265 wxCoord borderBetweenFields
;
266 wxRect rect
= self
->GetTotalFieldRect(&borderBetweenFields
);
268 // it's the caller responsability to check this, if unsure - call
269 // GetFieldRect() instead
270 wxCHECK_MSG( !m_widthsAbs
.IsEmpty(), rect
,
271 _T("can't be called if we don't have the widths") );
273 for ( int i
= 0; i
<= n
; i
++ )
275 rect
.width
= m_widthsAbs
[i
];
278 rect
.x
+= rect
.width
+ borderBetweenFields
;
284 wxCoord
wxStatusBarUniv::GetHeight() const
286 return GetCharHeight() + 2*GetBorderY();
289 wxSize
wxStatusBarUniv::DoGetBestSize() const
291 return wxSize(100, GetHeight());
294 void wxStatusBarUniv::DoSetSize(int x
, int y
,
295 int width
, int WXUNUSED(height
),
298 wxStatusBarBase::DoSetSize(x
, y
, width
, GetHeight(), sizeFlags
);
301 // ----------------------------------------------------------------------------
303 // ----------------------------------------------------------------------------
305 void wxStatusBarUniv::SetMinHeight(int WXUNUSED(height
))
307 // nothing to do here, we don't support it - and why would we?
310 int wxStatusBarUniv::GetBorderX() const
312 return m_renderer
->GetStatusBarBorders().x
+
313 m_renderer
->GetStatusBarFieldMargins().x
;
316 int wxStatusBarUniv::GetBorderY() const
318 return m_renderer
->GetStatusBarBorders().y
+
319 m_renderer
->GetStatusBarFieldMargins().y
;
322 #endif // wxUSE_STATUSBAR