1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        univ/ctrlrend.cpp 
   3 // Purpose:     wxControlRenderer 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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  21     #pragma implementation "renderer.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  33     #include "wx/control.h" 
  34     #include "wx/checklst.h" 
  35     #include "wx/listbox.h" 
  36     #include "wx/scrolbar.h" 
  43 #include "wx/univ/theme.h" 
  44 #include "wx/univ/renderer.h" 
  45 #include "wx/univ/colschem.h" 
  51 // ============================================================================ 
  53 // ============================================================================ 
  55 // ---------------------------------------------------------------------------- 
  56 // wxRenderer: drawing helpers 
  57 // ---------------------------------------------------------------------------- 
  59 void wxRenderer::StandardDrawFrame(wxDC
& dc
, 
  60                                    const wxRect
& rectFrame
, 
  61                                    const wxRect
& rectLabel
) 
  63     // draw left, bottom and right lines entirely 
  64     DrawVerticalLine(dc
, rectFrame
.GetLeft(), 
  65                      rectFrame
.GetTop(), rectFrame
.GetBottom() - 2); 
  66     DrawHorizontalLine(dc
, rectFrame
.GetBottom() - 1, 
  67                        rectFrame
.GetLeft(), rectFrame
.GetRight()); 
  68     DrawVerticalLine(dc
, rectFrame
.GetRight() - 1, 
  69                      rectFrame
.GetTop(), rectFrame
.GetBottom() - 1); 
  71     // and 2 parts of the top line 
  72     DrawHorizontalLine(dc
, rectFrame
.GetTop(), 
  73                        rectFrame
.GetLeft() + 1, rectLabel
.GetLeft()); 
  74     DrawHorizontalLine(dc
, rectFrame
.GetTop(), 
  75                        rectLabel
.GetRight(), rectFrame
.GetRight() - 2); 
  79 void wxRenderer::StandardDrawTextLine(wxDC
& dc
, 
  82                                       int selStart
, int selEnd
, 
  85     if ( (selStart 
== -1) || !(flags 
& wxCONTROL_FOCUSED
) ) 
  88         dc
.DrawText(text
, rect
.x
, rect
.y
); 
  90     else // we have selection 
  95         // draw the part before selection 
  96         wxString 
s(text
, (size_t)selStart
); 
  99             dc
.DrawText(s
, x
, rect
.y
); 
 101             dc
.GetTextExtent(s
, &width
, NULL
); 
 105         // draw the selection itself 
 106         s 
= wxString(text
.c_str() + selStart
, text
.c_str() + selEnd
); 
 109             wxColour colFg 
= dc
.GetTextForeground(), 
 110                      colBg 
= dc
.GetTextBackground(); 
 111             dc
.SetTextForeground(wxTHEME_COLOUR(HIGHLIGHT_TEXT
)); 
 112             dc
.SetTextBackground(wxTHEME_COLOUR(HIGHLIGHT
)); 
 113             dc
.SetBackgroundMode(wxSOLID
); 
 115             dc
.DrawText(s
, x
, rect
.y
); 
 116             dc
.GetTextExtent(s
, &width
, NULL
); 
 119             dc
.SetBackgroundMode(wxTRANSPARENT
); 
 120             dc
.SetTextBackground(colBg
); 
 121             dc
.SetTextForeground(colFg
); 
 124         // draw the final part 
 125         s 
= text
.c_str() + selEnd
; 
 128             dc
.DrawText(s
, x
, rect
.y
); 
 133 // ---------------------------------------------------------------------------- 
 134 // wxRenderer: scrollbar geometry 
 135 // ---------------------------------------------------------------------------- 
 138 void wxRenderer::StandardScrollBarThumbSize(wxCoord length
, 
 145     // the thumb can't be made less than this number of pixels 
 146     static const wxCoord thumbMinWidth 
= 8; // FIXME: should be configurable 
 148     *thumbStart 
= (length
*thumbPos
) / range
; 
 149     *thumbEnd 
= (length
*(thumbPos 
+ thumbSize
)) / range
; 
 151     if ( *thumbEnd 
- *thumbStart 
< thumbMinWidth 
) 
 153         // adjust the end if possible 
 154         if ( *thumbStart 
<= length 
- thumbMinWidth 
) 
 156             // yes, just make it wider 
 157             *thumbEnd 
= *thumbStart 
+ thumbMinWidth
; 
 159         else // it is at the bottom of the scrollbar 
 161             // so move it a bit up 
 162             *thumbStart 
= length 
- thumbMinWidth
; 
 169 wxRect 
wxRenderer::StandardGetScrollbarRect(const wxScrollBar 
*scrollbar
, 
 170                                             wxScrollBar::Element elem
, 
 172                                             const wxSize
& sizeArrow
) 
 174     if ( thumbPos 
== -1 ) 
 176         thumbPos 
= scrollbar
->GetThumbPosition(); 
 179     wxSize sizeTotal 
= scrollbar
->GetClientSize(); 
 180     wxCoord 
*start
, *width
, length
, arrow
; 
 182     if ( scrollbar
->IsVertical() ) 
 185         rect
.width 
= sizeTotal
.x
; 
 186         length 
= sizeTotal
.y
; 
 188         width 
= &rect
.height
; 
 194         rect
.height 
= sizeTotal
.y
; 
 195         length 
= sizeTotal
.x
; 
 203         case wxScrollBar::Element_Arrow_Line_1
: 
 208         case wxScrollBar::Element_Arrow_Line_2
: 
 209             *start 
= length 
- arrow
; 
 213         case wxScrollBar::Element_Arrow_Page_1
: 
 214         case wxScrollBar::Element_Arrow_Page_2
: 
 215             // we don't have them at all 
 218         case wxScrollBar::Element_Thumb
: 
 219         case wxScrollBar::Element_Bar_1
: 
 220         case wxScrollBar::Element_Bar_2
: 
 221             // we need to calculate the thumb position - do it 
 224                 wxCoord thumbStart
, thumbEnd
; 
 225                 int range 
= scrollbar
->GetRange(); 
 233                     StandardScrollBarThumbSize(length
, 
 235                                                scrollbar
->GetThumbSize(), 
 241                 if ( elem 
== wxScrollBar::Element_Thumb 
) 
 244                     *width 
= thumbEnd 
- thumbStart
; 
 246                 else if ( elem 
== wxScrollBar::Element_Bar_1 
) 
 251                 else // elem == wxScrollBar::Element_Bar_2 
 254                     *width 
= length 
- thumbEnd
; 
 257                 // everything is relative to the start of the shaft so far 
 262         case wxScrollBar::Element_Max
: 
 264             wxFAIL_MSG( _T("unknown scrollbar element") ); 
 271 wxCoord 
wxRenderer::StandardScrollBarSize(const wxScrollBar 
*scrollbar
, 
 272                                           const wxSize
& sizeArrowSB
) 
 274     wxCoord sizeArrow
, sizeTotal
; 
 275     if ( scrollbar
->GetWindowStyle() & wxVERTICAL 
) 
 277         sizeArrow 
= sizeArrowSB
.y
; 
 278         sizeTotal 
= scrollbar
->GetSize().y
; 
 282         sizeArrow 
= sizeArrowSB
.x
; 
 283         sizeTotal 
= scrollbar
->GetSize().x
; 
 286     return sizeTotal 
- 2*sizeArrow
; 
 290 wxCoord 
wxRenderer::StandardScrollbarToPixel(const wxScrollBar 
*scrollbar
, 
 292                                              const wxSize
& sizeArrow
) 
 294     int range 
= scrollbar
->GetRange(); 
 297         // the only valid position anyhow 
 301     if ( thumbPos 
== -1 ) 
 303         // by default use the current thumb position 
 304         thumbPos 
= scrollbar
->GetThumbPosition(); 
 307     return ( thumbPos
*StandardScrollBarSize(scrollbar
, sizeArrow
) ) / range
 
 308              + (scrollbar
->IsVertical() ? sizeArrow
.y 
: sizeArrow
.x
); 
 312 int wxRenderer::StandardPixelToScrollbar(const wxScrollBar 
*scrollbar
, 
 314                                          const wxSize
& sizeArrow
) 
 316     return ( (coord 
- (scrollbar
->IsVertical() ? sizeArrow
.y 
: sizeArrow
.x
)) * 
 317                scrollbar
->GetRange() ) / 
 318                StandardScrollBarSize(scrollbar
, sizeArrow
); 
 322 wxHitTest 
wxRenderer::StandardHitTestScrollbar(const wxScrollBar 
*scrollbar
, 
 324                                                const wxSize
& sizeArrowSB
) 
 326     // we only need to work with either x or y coord depending on the 
 327     // orientation, choose one (but still check the other one to verify if the 
 328     // mouse is in the window at all) 
 329     wxCoord coord
, sizeArrow
, sizeTotal
; 
 330     wxSize size 
= scrollbar
->GetSize(); 
 331     if ( scrollbar
->GetWindowStyle() & wxVERTICAL 
) 
 333         if ( pt
.x 
< 0 || pt
.x 
> size
.x 
) 
 337         sizeArrow 
= sizeArrowSB
.y
; 
 342         if ( pt
.y 
< 0 || pt
.y 
> size
.y 
) 
 346         sizeArrow 
= sizeArrowSB
.x
; 
 350     // test for the arrows first as it's faster 
 351     if ( coord 
< 0 || coord 
> sizeTotal 
) 
 355     else if ( coord 
< sizeArrow 
) 
 357         return wxHT_SCROLLBAR_ARROW_LINE_1
; 
 359     else if ( coord 
> sizeTotal 
- sizeArrow 
) 
 361         return wxHT_SCROLLBAR_ARROW_LINE_2
; 
 365         // calculate the thumb position in pixels 
 366         sizeTotal 
-= 2*sizeArrow
; 
 367         wxCoord thumbStart
, thumbEnd
; 
 368         int range 
= scrollbar
->GetRange(); 
 371             // clicking the scrollbar without range has no effect 
 376             StandardScrollBarThumbSize(sizeTotal
, 
 377                                        scrollbar
->GetThumbPosition(), 
 378                                        scrollbar
->GetThumbSize(), 
 384         // now compare with the thumb position 
 386         if ( coord 
< thumbStart 
) 
 387             return wxHT_SCROLLBAR_BAR_1
; 
 388         else if ( coord 
> thumbEnd 
) 
 389             return wxHT_SCROLLBAR_BAR_2
; 
 391             return wxHT_SCROLLBAR_THUMB
; 
 395 wxRenderer::~wxRenderer() 
 399 // ---------------------------------------------------------------------------- 
 401 // ---------------------------------------------------------------------------- 
 403 wxControlRenderer::wxControlRenderer(wxWindow 
*window
, 
 405                                      wxRenderer 
*renderer
) 
 409     m_renderer 
= renderer
; 
 411     wxSize size 
= m_window
->GetClientSize(); 
 414     m_rect
.width 
= size
.x
; 
 415     m_rect
.height 
= size
.y
; 
 418 void wxControlRenderer::DrawLabel(const wxBitmap
& bitmap
, 
 419                                   wxCoord marginX
, wxCoord marginY
) 
 421     m_dc
.SetBackgroundMode(wxTRANSPARENT
); 
 422     m_dc
.SetFont(m_window
->GetFont()); 
 423     m_dc
.SetTextForeground(m_window
->GetForegroundColour()); 
 425     wxString label 
= m_window
->GetLabel(); 
 426     if ( !label
.empty() || bitmap
.Ok() ) 
 428         wxRect rectLabel 
= m_rect
; 
 431             rectLabel
.Inflate(-marginX
, -marginY
); 
 434         wxControl 
*ctrl 
= wxStaticCast(m_window
, wxControl
); 
 436         m_renderer
->DrawButtonLabel(m_dc
, 
 440                                     m_window
->GetStateFlags(), 
 441                                     ctrl
->GetAlignment(), 
 442                                     ctrl
->GetAccelIndex()); 
 446 void wxControlRenderer::DrawFrame() 
 448     m_dc
.SetFont(m_window
->GetFont()); 
 449     m_dc
.SetTextForeground(m_window
->GetForegroundColour()); 
 450     m_dc
.SetTextBackground(m_window
->GetBackgroundColour()); 
 452     wxControl 
*ctrl 
= wxStaticCast(m_window
, wxControl
); 
 454     m_renderer
->DrawFrame(m_dc
, 
 455                           m_window
->GetLabel(), 
 457                           m_window
->GetStateFlags(), 
 458                           ctrl
->GetAlignment(), 
 459                           ctrl
->GetAccelIndex()); 
 462 void wxControlRenderer::DrawButtonBorder() 
 464     int flags 
= m_window
->GetStateFlags(); 
 466     m_renderer
->DrawButtonBorder(m_dc
, m_rect
, flags
, &m_rect
); 
 469     // m_renderer->DrawButtonSurface(m_dc, wxTHEME_BG_COLOUR(m_window), m_rect, flags ); 
 472 void wxControlRenderer::DrawBitmap(const wxBitmap
& bitmap
) 
 474     int style 
= m_window
->GetWindowStyle(); 
 475     DrawBitmap(m_dc
, bitmap
, m_rect
, 
 476                style 
& wxALIGN_MASK
, 
 477                style 
& wxBI_EXPAND 
? wxEXPAND 
: wxSTRETCH_NOT
); 
 481 void wxControlRenderer::DrawBitmap(wxDC 
&dc
, 
 482                                    const wxBitmap
& bitmap
, 
 487     // we may change the bitmap if we stretch it 
 488     wxBitmap bmp 
= bitmap
; 
 492     int width 
= bmp
.GetWidth(), 
 493         height 
= bmp
.GetHeight(); 
 497     if ( stretch 
& wxTILE 
) 
 500         for ( ; x 
< rect
.width
; x 
+= width 
) 
 502             for ( y 
= 0; y 
< rect
.height
; y 
+= height 
) 
 504                 // no need to use mask here as we cover the entire window area 
 505                 dc
.DrawBitmap(bmp
, x
, y
); 
 509     else if ( stretch 
& wxEXPAND 
) 
 511         // stretch bitmap to fill the entire control 
 512         bmp 
= wxBitmap(wxImage(bmp
.ConvertToImage()).Scale(rect
.width
, rect
.height
)); 
 514     else // not stretched, not tiled 
 516         if ( alignment 
& wxALIGN_RIGHT 
) 
 518             x 
= rect
.GetRight() - width
; 
 520         else if ( alignment 
& wxALIGN_CENTRE 
) 
 522             x 
= (rect
.GetLeft() + rect
.GetRight() - width 
+ 1) / 2; 
 524         else // alignment & wxALIGN_LEFT 
 529         if ( alignment 
& wxALIGN_BOTTOM 
) 
 531             y 
= rect
.GetBottom() - height
; 
 533         else if ( alignment 
& wxALIGN_CENTRE_VERTICAL 
) 
 535             y 
= (rect
.GetTop() + rect
.GetBottom() - height 
+ 1) / 2; 
 537         else // alignment & wxALIGN_TOP 
 544     dc
.DrawBitmap(bmp
, x
, y
, true /* use mask */); 
 547 void wxControlRenderer::DrawScrollbar(const wxScrollBar 
*scrollbar
, 
 548                                       int WXUNUSED(thumbPosOld
)) 
 550     // we will only redraw the parts which must be redrawn and not everything 
 551     wxRegion rgnUpdate 
= scrollbar
->GetUpdateRegion(); 
 554         wxRect rectUpdate 
= rgnUpdate
.GetBox(); 
 555         wxLogTrace(_T("scrollbar"), 
 556                    _T("%s redraw: update box is (%d, %d)-(%d, %d)"), 
 557                    scrollbar
->IsVertical() ? _T("vert") : _T("horz"), 
 558                    rectUpdate
.GetLeft(), 
 560                    rectUpdate
.GetRight(), 
 561                    rectUpdate
.GetBottom()); 
 563 #if 0 //def WXDEBUG_SCROLLBAR 
 564         static bool s_refreshDebug 
= false; 
 565         if ( s_refreshDebug 
) 
 567             wxClientDC 
dc(wxConstCast(scrollbar
, wxScrollBar
)); 
 568             dc
.SetBrush(*wxRED_BRUSH
); 
 569             dc
.SetPen(*wxTRANSPARENT_PEN
); 
 570             dc
.DrawRectangle(rectUpdate
); 
 572             // under Unix we use "--sync" X option for this 
 578 #endif // WXDEBUG_SCROLLBAR 
 581     wxOrientation orient 
= scrollbar
->IsVertical() ? wxVERTICAL
 
 585     for ( int nBar 
= 0; nBar 
< 2; nBar
++ ) 
 587         wxScrollBar::Element elem 
= 
 588             (wxScrollBar::Element
)(wxScrollBar::Element_Bar_1 
+ nBar
); 
 590         wxRect rectBar 
= m_renderer
->GetScrollbarRect(scrollbar
, elem
); 
 592         if ( rgnUpdate
.Contains(rectBar
) ) 
 594             wxLogTrace(_T("scrollbar"), 
 595                        _T("drawing bar part %d at (%d, %d)-(%d, %d)"), 
 600                        rectBar
.GetBottom()); 
 602             m_renderer
->DrawScrollbarShaft(m_dc
, 
 605                                            scrollbar
->GetState(elem
)); 
 610     for ( int nArrow 
= 0; nArrow 
< 2; nArrow
++ ) 
 612         wxScrollBar::Element elem 
= 
 613             (wxScrollBar::Element
)(wxScrollBar::Element_Arrow_Line_1 
+ nArrow
); 
 615         wxRect rectArrow 
= m_renderer
->GetScrollbarRect(scrollbar
, elem
); 
 616         if ( rgnUpdate
.Contains(rectArrow
) ) 
 618             wxLogTrace(_T("scrollbar"), 
 619                        _T("drawing arrow %d at (%d, %d)-(%d, %d)"), 
 623                        rectArrow
.GetRight(), 
 624                        rectArrow
.GetBottom()); 
 626             scrollbar
->GetArrows().DrawArrow
 
 628                 (wxScrollArrows::Arrow
)nArrow
, 
 631                 true // draw a scrollbar arrow, not just an arrow 
 636     // TODO: support for page arrows 
 639     wxScrollBar::Element elem 
= wxScrollBar::Element_Thumb
; 
 640     wxRect rectThumb 
= m_renderer
->GetScrollbarRect(scrollbar
, elem
); 
 641     if ( rectThumb
.width 
&& rectThumb
.height 
&& rgnUpdate
.Contains(rectThumb
) ) 
 643         wxLogTrace(_T("scrollbar"), 
 644                    _T("drawing thumb at (%d, %d)-(%d, %d)"), 
 647                    rectThumb
.GetRight(), 
 648                    rectThumb
.GetBottom()); 
 650         m_renderer
->DrawScrollbarThumb(m_dc
, 
 653                                        scrollbar
->GetState(elem
)); 
 657 void wxControlRenderer::DrawLine(wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
) 
 659     wxASSERT_MSG( x1 
== x2 
|| y1 
== y2
, 
 660                   _T("line must be either horizontal or vertical") ); 
 663         m_renderer
->DrawVerticalLine(m_dc
, x1
, y1
, y2
); 
 665         m_renderer
->DrawHorizontalLine(m_dc
, y1
, x1
, x2
); 
 670 void wxControlRenderer::DrawItems(const wxListBox 
*lbox
, 
 671                                   size_t itemFirst
, size_t itemLast
) 
 673     DoDrawItems(lbox
, itemFirst
, itemLast
); 
 676 void wxControlRenderer::DoDrawItems(const wxListBox 
*lbox
, 
 677                                     size_t itemFirst
, size_t itemLast
, 
 678 #if wxUSE_CHECKLISTBOX 
 681                                     bool WXUNUSED(isCheckLbox
)) 
 684     // prepare for the drawing: calc the initial position 
 685     wxCoord lineHeight 
= lbox
->GetLineHeight(); 
 687     // note that SetClippingRegion() needs the physical (unscrolled) 
 688     // coordinates while we use the logical (scrolled) ones for the drawing 
 691     wxSize size 
= lbox
->GetClientSize(); 
 693     rect
.height 
= size
.y
; 
 695     // keep the text inside the client rect or we will overwrite the vertical 
 696     // scrollbar for the long strings 
 697     m_dc
.SetClippingRegion(rect
.x
, rect
.y
, rect
.width 
+ 1, rect
.height 
+ 1); 
 699     // adjust the rect position now 
 700     lbox
->CalcScrolledPosition(rect
.x
, rect
.y
, &rect
.x
, &rect
.y
); 
 701     rect
.y 
+= itemFirst
*lineHeight
; 
 702     rect
.height 
= lineHeight
; 
 704     // the rect should go to the right visible border so adjust the width if x 
 705     // is shifted (rightmost point should stay the same) 
 706     rect
.width 
-= rect
.x
; 
 708     // we'll keep the text colour unchanged 
 709     m_dc
.SetTextForeground(lbox
->GetForegroundColour()); 
 711     // an item should have the focused rect only when the lbox has focus, so 
 712     // make sure that we never set wxCONTROL_FOCUSED flag if it doesn't 
 713     int itemCurrent 
= wxWindow::FindFocus() == (wxWindow 
*)lbox 
// cast needed 
 714                         ? lbox
->GetCurrentItem() 
 716     for ( size_t n 
= itemFirst
; n 
< itemLast
; n
++ ) 
 719         if ( (int)n 
== itemCurrent 
) 
 720             flags 
|= wxCONTROL_FOCUSED
; 
 721         if ( lbox
->IsSelected(n
) ) 
 722             flags 
|= wxCONTROL_SELECTED
; 
 724 #if wxUSE_CHECKLISTBOX 
 727             wxCheckListBox 
*checklstbox 
= wxStaticCast(lbox
, wxCheckListBox
); 
 728             if ( checklstbox
->IsChecked(n
) ) 
 729                 flags 
|= wxCONTROL_CHECKED
; 
 731             m_renderer
->DrawCheckItem(m_dc
, lbox
->GetString(n
), 
 737 #endif // wxUSE_CHECKLISTBOX 
 739             m_renderer
->DrawItem(m_dc
, lbox
->GetString(n
), rect
, flags
); 
 742         rect
.y 
+= lineHeight
; 
 746 #endif // wxUSE_LISTBOX 
 748 #if wxUSE_CHECKLISTBOX 
 750 void wxControlRenderer::DrawCheckItems(const wxCheckListBox 
*lbox
, 
 751                                        size_t itemFirst
, size_t itemLast
) 
 753     DoDrawItems(lbox
, itemFirst
, itemLast
, true); 
 756 #endif // wxUSE_CHECKLISTBOX 
 760 void wxControlRenderer::DrawProgressBar(const wxGauge 
*gauge
) 
 763     m_dc
.SetBrush(wxBrush(m_window
->GetBackgroundColour(), wxSOLID
)); 
 764     m_dc
.SetPen(*wxTRANSPARENT_PEN
); 
 765     m_dc
.DrawRectangle(m_rect
); 
 767     int max 
= gauge
->GetRange(); 
 774     // calc the filled rect 
 775     int pos 
= gauge
->GetValue(); 
 776     int left 
= max 
- pos
; 
 778     wxRect rect 
= m_rect
; 
 779     rect
.Deflate(1); // FIXME this depends on the border width 
 781     wxColour col 
= m_window
->UseFgCol() ? m_window
->GetForegroundColour() 
 782                                         : wxTHEME_COLOUR(GAUGE
); 
 783     m_dc
.SetBrush(wxBrush(col
, wxSOLID
)); 
 785     if ( gauge
->IsSmooth() ) 
 787         // just draw the rectangle in one go 
 788         if ( gauge
->IsVertical() ) 
 790             // vert bars grow from bottom to top 
 791             wxCoord dy 
= ((rect
.height 
- 1) * left
) / max
; 
 797             // grow from left to right 
 798             rect
.width 
-= ((rect
.width 
- 1) * left
) / max
; 
 801         m_dc
.DrawRectangle(rect
); 
 805         wxSize sizeStep 
= m_renderer
->GetProgressBarStep(); 
 806         int step 
= gauge
->IsVertical() ? sizeStep
.y 
: sizeStep
.x
; 
 808         // we divide by it below! 
 809         wxCHECK_RET( step
, _T("invalid wxGauge step") ); 
 811         // round up to make the progress appear to start faster 
 812         int lenTotal 
= gauge
->IsVertical() ? rect
.height 
: rect
.width
; 
 813         int steps 
= ((lenTotal 
+ step 
- 1) * pos
) / (max 
* step
); 
 815         // calc the coords of one small rect 
 817         if ( gauge
->IsVertical() ) 
 819             // draw from bottom to top: so first set y to the bottom 
 820             rect
.y 
+= rect
.height 
- 1; 
 822             // then adjust the height 
 825             // and then adjust y again to be what it should for the first rect 
 826             rect
.y 
-= rect
.height
; 
 831             // remember that this will be the coord which will change 
 839             // don't leave 2 empty pixels in the beginning 
 849         for ( int n 
= 0; n 
< steps
; n
++ ) 
 851             wxRect rectSegment 
= rect
; 
 852             rectSegment
.Deflate(dx
, dy
); 
 854             m_dc
.DrawRectangle(rectSegment
); 
 859                 // this can only happen for the last step of vertical gauge 
 860                 rect
.height 
= *px 
- step 
- 1; 
 863             else if ( *px 
> lenTotal 
- step 
) 
 865                 // this can only happen for the last step of horizontal gauge 
 866                 rect
.width 
= lenTotal 
- *px 
- 1; 
 872 #endif // wxUSE_GAUGE