1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/univ/statusbr.cpp
3 // Purpose: wxStatusBar implementation
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 #include "wx/wxprec.h"
27 #include "wx/statusbr.h"
30 #include "wx/settings.h"
31 #include "wx/dcclient.h"
32 #include "wx/toplevel.h"
35 #include "wx/univ/renderer.h"
37 // ============================================================================
39 // ============================================================================
41 BEGIN_EVENT_TABLE(wxStatusBarUniv
, wxStatusBarBase
)
42 EVT_SIZE(wxStatusBarUniv::OnSize
)
44 WX_EVENT_TABLE_INPUT_CONSUMER(wxStatusBarUniv
)
47 WX_FORWARD_TO_INPUT_CONSUMER(wxStatusBarUniv
)
49 // ----------------------------------------------------------------------------
51 // ----------------------------------------------------------------------------
53 void wxStatusBarUniv::Init()
57 bool wxStatusBarUniv::Create(wxWindow
*parent
,
62 if ( !wxWindow::Create(parent
, id
,
63 wxDefaultPosition
, wxDefaultSize
,
71 CreateInputHandler(wxINP_HANDLER_STATUSBAR
);
73 SetSize(DoGetBestSize());
78 // ----------------------------------------------------------------------------
80 // ----------------------------------------------------------------------------
82 wxRect
wxStatusBarUniv::GetTotalFieldRect(wxCoord
*borderBetweenFields
)
84 wxRect rect
= GetClientRect();
86 // no, don't do this - the borders are meant to be inside this rect
87 // wxSize sizeBorders =
88 if ( borderBetweenFields
)
89 *borderBetweenFields
= m_renderer
->GetStatusBarBorderBetweenFields();
90 //rect.Deflate(sizeBorders.x, sizeBorders.y);
92 // recalc the field widths if needed
93 if ( m_widthsAbs
.IsEmpty() )
95 // the total width for the fields doesn't include the borders between
97 m_widthsAbs
= CalculateAbsWidths(rect
.width
-
98 *borderBetweenFields
*(m_panes
.GetCount() - 1));
104 void wxStatusBarUniv::DoDraw(wxControlRenderer
*renderer
)
106 // get the fields rect
107 wxCoord borderBetweenFields
;
108 wxRect rect
= GetTotalFieldRect(&borderBetweenFields
);
111 wxDC
& dc
= renderer
->GetDC();
112 dc
.SetFont(GetFont());
113 dc
.SetTextForeground(GetForegroundColour());
115 // do draw the fields
116 int flags
= IsEnabled() ? 0 : (int)wxCONTROL_DISABLED
;
117 for ( int n
= 0; n
< (int)m_panes
.GetCount(); n
++ )
119 rect
.width
= m_widthsAbs
[n
];
121 if ( IsExposed(rect
) )
123 wxTopLevelWindow
*parentTLW
= wxDynamicCast(GetParent(), wxTopLevelWindow
);
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
128 if ( n
== (int)m_panes
.GetCount() - 1 &&
129 HasFlag(wxSTB_SIZEGRIP
) &&
130 GetParent()->HasFlag(wxRESIZE_BORDER
) &&
131 parentTLW
&& !parentTLW
->IsMaximized() )
133 flags
|= wxCONTROL_SIZEGRIP
;
136 m_renderer
->DrawStatusField(dc
, rect
, GetStatusText(n
), flags
, m_panes
[n
].GetStyle());
139 rect
.x
+= rect
.width
+ borderBetweenFields
;
143 void wxStatusBarUniv::DoUpdateStatusText(int i
)
146 if ( GetFieldRect(i
, rect
) )
152 // ----------------------------------------------------------------------------
153 // fields count/widths
154 // ----------------------------------------------------------------------------
156 void wxStatusBarUniv::SetFieldsCount(int number
, const int *widths
)
158 wxStatusBarBase::SetFieldsCount(number
, widths
);
163 void wxStatusBarUniv::SetStatusWidths(int n
, const int widths
[])
165 wxStatusBarBase::SetStatusWidths(n
, widths
);
170 // ----------------------------------------------------------------------------
172 // ----------------------------------------------------------------------------
174 void wxStatusBarUniv::OnSize(wxSizeEvent
& event
)
176 // we don't need to refresh the fields whose width didn't change, so find
177 // the first field whose width did change and refresh starting from it
179 if ( m_bSameWidthForAllPanes
)
181 // hence all fields widths have changed
186 for ( field
= 0; field
< m_panes
.GetCount(); field
++ )
188 if ( m_panes
[field
].GetWidth() < 0 )
196 if ( field
< m_panes
.GetCount() )
198 // call this before invalidating the old widths as we want to use them,
200 wxRect rect
= DoGetFieldRect(field
);
202 // invalidate the widths, we'll have to recalc them
205 // refresh everything after the first invalid field
207 rect
.SetRight(event
.GetSize().x
);
208 rect
.height
= event
.GetSize().y
;
215 bool wxStatusBarUniv::GetFieldRect(int n
, wxRect
& rect
) const
217 wxCHECK_MSG( n
>= 0 && (size_t)n
< m_panes
.GetCount(), false,
218 wxT("invalid field index in GetFieldRect()") );
220 // this is a fix for a bug exhibited by the statbar sample: if
221 // GetFieldRect() is called from the derived class OnSize() handler, then
222 // our geometry info is wrong as our OnSize() didn't invalidate m_widthsAbs
223 // yet - so recalc it just in case
224 wxConstCast(this, wxStatusBarUniv
)->m_widthsAbs
.Empty();
226 rect
= DoGetFieldRect(n
);
231 wxRect
wxStatusBarUniv::DoGetFieldRect(int n
) const
233 wxStatusBarUniv
*self
= wxConstCast(this, wxStatusBarUniv
);
235 wxCoord borderBetweenFields
;
236 wxRect rect
= self
->GetTotalFieldRect(&borderBetweenFields
);
238 // it's the caller responsability to check this, if unsure - call
239 // GetFieldRect() instead
240 wxCHECK_MSG( !m_widthsAbs
.IsEmpty(), rect
,
241 wxT("can't be called if we don't have the widths") );
243 for ( int i
= 0; i
<= n
; i
++ )
245 rect
.width
= m_widthsAbs
[i
];
248 rect
.x
+= rect
.width
+ borderBetweenFields
;
254 wxCoord
wxStatusBarUniv::GetHeight() const
256 return GetCharHeight() + 2*GetBorderY();
259 wxSize
wxStatusBarUniv::DoGetBestSize() const
261 return wxSize(100, GetHeight());
264 void wxStatusBarUniv::DoSetSize(int x
, int y
,
265 int width
, int WXUNUSED(height
),
268 wxStatusBarBase::DoSetSize(x
, y
, width
, GetHeight(), sizeFlags
);
271 // ----------------------------------------------------------------------------
273 // ----------------------------------------------------------------------------
275 void wxStatusBarUniv::SetMinHeight(int WXUNUSED(height
))
277 // nothing to do here, we don't support it - and why would we?
280 int wxStatusBarUniv::GetBorderX() const
282 return m_renderer
->GetStatusBarBorders().x
+
283 m_renderer
->GetStatusBarFieldMargins().x
;
286 int wxStatusBarUniv::GetBorderY() const
288 return m_renderer
->GetStatusBarBorders().y
+
289 m_renderer
->GetStatusBarFieldMargins().y
;
292 #endif // wxUSE_STATUSBAR