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(wxSTB_SIZEGRIP
) && 
 131                  GetParent()->HasFlag(wxRESIZE_BORDER
) && 
 132                  parentTLW 
&& !parentTLW
->IsMaximized() ) 
 134                 flags 
|= wxCONTROL_SIZEGRIP
; 
 137             m_renderer
->DrawStatusField(dc
, rect
, GetStatusText(n
), flags
, m_panes
[n
].GetStyle()); 
 140         rect
.x 
+= rect
.width 
+ borderBetweenFields
; 
 144 void wxStatusBarUniv::DoUpdateStatusText(int i
) 
 147     if ( GetFieldRect(i
, rect
) ) 
 153 // ---------------------------------------------------------------------------- 
 154 // fields count/widths 
 155 // ---------------------------------------------------------------------------- 
 157 void wxStatusBarUniv::SetFieldsCount(int number
, const int *widths
) 
 159     wxStatusBarBase::SetFieldsCount(number
, widths
); 
 164 void wxStatusBarUniv::SetStatusWidths(int n
, const int widths
[]) 
 166     wxStatusBarBase::SetStatusWidths(n
, widths
); 
 171 // ---------------------------------------------------------------------------- 
 173 // ---------------------------------------------------------------------------- 
 175 void wxStatusBarUniv::OnSize(wxSizeEvent
& event
) 
 177     // we don't need to refresh the fields whose width didn't change, so find 
 178     // the first field whose width did change and refresh starting from it 
 180     if ( m_bSameWidthForAllPanes 
) 
 182         // hence all fields widths have changed 
 187         for ( field 
= 0; field 
< m_panes
.GetCount(); field
++ ) 
 189             if ( m_panes
[field
].GetWidth() < 0 ) 
 197     if ( field 
< m_panes
.GetCount() ) 
 199         // call this before invalidating the old widths as we want to use them, 
 201         wxRect rect 
= DoGetFieldRect(field
); 
 203         // invalidate the widths, we'll have to recalc them 
 206         // refresh everything after the first invalid field 
 208         rect
.SetRight(event
.GetSize().x
); 
 209         rect
.height 
= event
.GetSize().y
; 
 216 bool wxStatusBarUniv::GetFieldRect(int n
, wxRect
& rect
) const 
 218     wxCHECK_MSG( n 
>= 0 && (size_t)n 
< m_panes
.GetCount(), false, 
 219                  wxT("invalid field index in GetFieldRect()") ); 
 221     // this is a fix for a bug exhibited by the statbar sample: if 
 222     // GetFieldRect() is called from the derived class OnSize() handler, then 
 223     // our geometry info is wrong as our OnSize() didn't invalidate m_widthsAbs 
 224     // yet - so recalc it just in case 
 225     wxConstCast(this, wxStatusBarUniv
)->m_widthsAbs
.Empty(); 
 227     rect 
= DoGetFieldRect(n
); 
 232 wxRect 
wxStatusBarUniv::DoGetFieldRect(int n
) const 
 234     wxStatusBarUniv 
*self 
= wxConstCast(this, wxStatusBarUniv
); 
 236     wxCoord borderBetweenFields
; 
 237     wxRect rect 
= self
->GetTotalFieldRect(&borderBetweenFields
); 
 239     // it's the caller responsability to check this, if unsure - call 
 240     // GetFieldRect() instead 
 241     wxCHECK_MSG( !m_widthsAbs
.IsEmpty(), rect
, 
 242                  wxT("can't be called if we don't have the widths") ); 
 244     for ( int i 
= 0; i 
<= n
; i
++ ) 
 246         rect
.width 
= m_widthsAbs
[i
]; 
 249             rect
.x 
+= rect
.width 
+ borderBetweenFields
; 
 255 wxCoord 
wxStatusBarUniv::GetHeight() const 
 257     return GetCharHeight() + 2*GetBorderY(); 
 260 wxSize 
wxStatusBarUniv::DoGetBestSize() const 
 262     return wxSize(100, GetHeight()); 
 265 void wxStatusBarUniv::DoSetSize(int x
, int y
, 
 266                                 int width
, int WXUNUSED(height
), 
 269     wxStatusBarBase::DoSetSize(x
, y
, width
, GetHeight(), sizeFlags
); 
 272 // ---------------------------------------------------------------------------- 
 274 // ---------------------------------------------------------------------------- 
 276 void wxStatusBarUniv::SetMinHeight(int WXUNUSED(height
)) 
 278     // nothing to do here, we don't support it - and why would we? 
 281 int wxStatusBarUniv::GetBorderX() const 
 283     return m_renderer
->GetStatusBarBorders().x 
+ 
 284            m_renderer
->GetStatusBarFieldMargins().x
; 
 287 int wxStatusBarUniv::GetBorderY() const 
 289     return m_renderer
->GetStatusBarBorders().y 
+ 
 290            m_renderer
->GetStatusBarFieldMargins().y
; 
 293 #endif // wxUSE_STATUSBAR