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 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  29     #include "wx/control.h" 
  30     #include "wx/checklst.h" 
  31     #include "wx/listbox.h" 
  32     #include "wx/scrolbar.h" 
  39 #include "wx/univ/theme.h" 
  40 #include "wx/univ/renderer.h" 
  41 #include "wx/univ/colschem.h" 
  47 // ============================================================================ 
  49 // ============================================================================ 
  51 // ---------------------------------------------------------------------------- 
  52 // wxRenderer: drawing helpers 
  53 // ---------------------------------------------------------------------------- 
  55 void wxRenderer::StandardDrawFrame(wxDC
& dc
, 
  56                                    const wxRect
& rectFrame
, 
  57                                    const wxRect
& rectLabel
) 
  59     // draw left, bottom and right lines entirely 
  60     DrawVerticalLine(dc
, rectFrame
.GetLeft(), 
  61                      rectFrame
.GetTop(), rectFrame
.GetBottom() - 2); 
  62     DrawHorizontalLine(dc
, rectFrame
.GetBottom() - 1, 
  63                        rectFrame
.GetLeft(), rectFrame
.GetRight()); 
  64     DrawVerticalLine(dc
, rectFrame
.GetRight() - 1, 
  65                      rectFrame
.GetTop(), rectFrame
.GetBottom() - 1); 
  67     // and 2 parts of the top line 
  68     DrawHorizontalLine(dc
, rectFrame
.GetTop(), 
  69                        rectFrame
.GetLeft() + 1, rectLabel
.GetLeft()); 
  70     DrawHorizontalLine(dc
, rectFrame
.GetTop(), 
  71                        rectLabel
.GetRight(), rectFrame
.GetRight() - 2); 
  75 void wxRenderer::StandardDrawTextLine(wxDC
& dc
, 
  78                                       int selStart
, int selEnd
, 
  81     if ( (selStart 
== -1) || !(flags 
& wxCONTROL_FOCUSED
) ) 
  84         dc
.DrawText(text
, rect
.x
, rect
.y
); 
  86     else // we have selection 
  91         // draw the part before selection 
  92         wxString 
s(text
, (size_t)selStart
); 
  95             dc
.DrawText(s
, x
, rect
.y
); 
  97             dc
.GetTextExtent(s
, &width
, NULL
); 
 101         // draw the selection itself 
 102         s 
= wxString(text
.c_str() + selStart
, text
.c_str() + selEnd
); 
 105             wxColour colFg 
= dc
.GetTextForeground(), 
 106                      colBg 
= dc
.GetTextBackground(); 
 107             dc
.SetTextForeground(wxTHEME_COLOUR(HIGHLIGHT_TEXT
)); 
 108             dc
.SetTextBackground(wxTHEME_COLOUR(HIGHLIGHT
)); 
 109             dc
.SetBackgroundMode(wxSOLID
); 
 111             dc
.DrawText(s
, x
, rect
.y
); 
 112             dc
.GetTextExtent(s
, &width
, NULL
); 
 115             dc
.SetBackgroundMode(wxTRANSPARENT
); 
 116             dc
.SetTextBackground(colBg
); 
 117             dc
.SetTextForeground(colFg
); 
 120         // draw the final part 
 121         s 
= text
.c_str() + selEnd
; 
 124             dc
.DrawText(s
, x
, rect
.y
); 
 129 // ---------------------------------------------------------------------------- 
 130 // wxRenderer: scrollbar geometry 
 131 // ---------------------------------------------------------------------------- 
 134 void wxRenderer::StandardScrollBarThumbSize(wxCoord length
, 
 141     // the thumb can't be made less than this number of pixels 
 142     static const wxCoord thumbMinWidth 
= 8; // FIXME: should be configurable 
 144     *thumbStart 
= (length
*thumbPos
) / range
; 
 145     *thumbEnd 
= (length
*(thumbPos 
+ thumbSize
)) / range
; 
 147     if ( *thumbEnd 
- *thumbStart 
< thumbMinWidth 
) 
 149         // adjust the end if possible 
 150         if ( *thumbStart 
<= length 
- thumbMinWidth 
) 
 152             // yes, just make it wider 
 153             *thumbEnd 
= *thumbStart 
+ thumbMinWidth
; 
 155         else // it is at the bottom of the scrollbar 
 157             // so move it a bit up 
 158             *thumbStart 
= length 
- thumbMinWidth
; 
 165 wxRect 
wxRenderer::StandardGetScrollbarRect(const wxScrollBar 
*scrollbar
, 
 166                                             wxScrollBar::Element elem
, 
 168                                             const wxSize
& sizeArrow
) 
 170     if ( thumbPos 
== -1 ) 
 172         thumbPos 
= scrollbar
->GetThumbPosition(); 
 175     wxSize sizeTotal 
= scrollbar
->GetClientSize(); 
 176     wxCoord 
*start
, *width
; 
 177     wxCoord length
, arrow
; 
 179     if ( scrollbar
->IsVertical() ) 
 182         rect
.width 
= sizeTotal
.x
; 
 183         length 
= sizeTotal
.y
; 
 185         width 
= &rect
.height
; 
 191         rect
.height 
= sizeTotal
.y
; 
 192         length 
= sizeTotal
.x
; 
 200         case wxScrollBar::Element_Arrow_Line_1
: 
 205         case wxScrollBar::Element_Arrow_Line_2
: 
 206             *start 
= length 
- arrow
; 
 210         case wxScrollBar::Element_Arrow_Page_1
: 
 211         case wxScrollBar::Element_Arrow_Page_2
: 
 212             // we don't have them at all 
 215         case wxScrollBar::Element_Thumb
: 
 216         case wxScrollBar::Element_Bar_1
: 
 217         case wxScrollBar::Element_Bar_2
: 
 218             // we need to calculate the thumb position - do it 
 221                 wxCoord thumbStart
, thumbEnd
; 
 222                 int range 
= scrollbar
->GetRange(); 
 230                     StandardScrollBarThumbSize(length
, 
 232                                                scrollbar
->GetThumbSize(), 
 238                 if ( elem 
== wxScrollBar::Element_Thumb 
) 
 241                     *width 
= thumbEnd 
- thumbStart
; 
 243                 else if ( elem 
== wxScrollBar::Element_Bar_1 
) 
 248                 else // elem == wxScrollBar::Element_Bar_2 
 251                     *width 
= length 
- thumbEnd
; 
 254                 // everything is relative to the start of the shaft so far 
 259         case wxScrollBar::Element_Max
: 
 261             wxFAIL_MSG( _T("unknown scrollbar element") ); 
 268 wxCoord 
wxRenderer::StandardScrollBarSize(const wxScrollBar 
*scrollbar
, 
 269                                           const wxSize
& sizeArrowSB
) 
 271     wxCoord sizeArrow
, sizeTotal
; 
 272     if ( scrollbar
->GetWindowStyle() & wxVERTICAL 
) 
 274         sizeArrow 
= sizeArrowSB
.y
; 
 275         sizeTotal 
= scrollbar
->GetSize().y
; 
 279         sizeArrow 
= sizeArrowSB
.x
; 
 280         sizeTotal 
= scrollbar
->GetSize().x
; 
 283     return sizeTotal 
- 2*sizeArrow
; 
 287 wxCoord 
wxRenderer::StandardScrollbarToPixel(const wxScrollBar 
*scrollbar
, 
 289                                              const wxSize
& sizeArrow
) 
 291     int range 
= scrollbar
->GetRange(); 
 294         // the only valid position anyhow 
 298     if ( thumbPos 
== -1 ) 
 300         // by default use the current thumb position 
 301         thumbPos 
= scrollbar
->GetThumbPosition(); 
 304     return ( thumbPos
*StandardScrollBarSize(scrollbar
, sizeArrow
) ) / range
 
 305              + (scrollbar
->IsVertical() ? sizeArrow
.y 
: sizeArrow
.x
); 
 309 int wxRenderer::StandardPixelToScrollbar(const wxScrollBar 
*scrollbar
, 
 311                                          const wxSize
& sizeArrow
) 
 313     return ( (coord 
- (scrollbar
->IsVertical() ? sizeArrow
.y 
: sizeArrow
.x
)) * 
 314                scrollbar
->GetRange() ) / 
 315                StandardScrollBarSize(scrollbar
, sizeArrow
); 
 319 wxHitTest 
wxRenderer::StandardHitTestScrollbar(const wxScrollBar 
*scrollbar
, 
 321                                                const wxSize
& sizeArrowSB
) 
 323     // we only need to work with either x or y coord depending on the 
 324     // orientation, choose one (but still check the other one to verify if the 
 325     // mouse is in the window at all) 
 326     wxCoord coord
, sizeArrow
, sizeTotal
; 
 327     wxSize size 
= scrollbar
->GetSize(); 
 328     if ( scrollbar
->GetWindowStyle() & wxVERTICAL 
) 
 330         if ( pt
.x 
< 0 || pt
.x 
> size
.x 
) 
 334         sizeArrow 
= sizeArrowSB
.y
; 
 339         if ( pt
.y 
< 0 || pt
.y 
> size
.y 
) 
 343         sizeArrow 
= sizeArrowSB
.x
; 
 347     // test for the arrows first as it's faster 
 348     if ( coord 
< 0 || coord 
> sizeTotal 
) 
 352     else if ( coord 
< sizeArrow 
) 
 354         return wxHT_SCROLLBAR_ARROW_LINE_1
; 
 356     else if ( coord 
> sizeTotal 
- sizeArrow 
) 
 358         return wxHT_SCROLLBAR_ARROW_LINE_2
; 
 362         // calculate the thumb position in pixels 
 363         sizeTotal 
-= 2*sizeArrow
; 
 364         wxCoord thumbStart
, thumbEnd
; 
 365         int range 
= scrollbar
->GetRange(); 
 368             // clicking the scrollbar without range has no effect 
 373             StandardScrollBarThumbSize(sizeTotal
, 
 374                                        scrollbar
->GetThumbPosition(), 
 375                                        scrollbar
->GetThumbSize(), 
 381         // now compare with the thumb position 
 383         if ( coord 
< thumbStart 
) 
 384             return wxHT_SCROLLBAR_BAR_1
; 
 385         else if ( coord 
> thumbEnd 
) 
 386             return wxHT_SCROLLBAR_BAR_2
; 
 388             return wxHT_SCROLLBAR_THUMB
; 
 392 wxRenderer::~wxRenderer() 
 396 // ---------------------------------------------------------------------------- 
 398 // ---------------------------------------------------------------------------- 
 400 wxControlRenderer::wxControlRenderer(wxWindow 
*window
, 
 402                                      wxRenderer 
*renderer
) 
 406     m_renderer 
= renderer
; 
 408     wxSize size 
= m_window
->GetClientSize(); 
 411     m_rect
.width 
= size
.x
; 
 412     m_rect
.height 
= size
.y
; 
 415 void wxControlRenderer::DrawLabel(const wxBitmap
& bitmap
, 
 416                                   wxCoord marginX
, wxCoord marginY
) 
 418     m_dc
.SetBackgroundMode(wxTRANSPARENT
); 
 419     m_dc
.SetFont(m_window
->GetFont()); 
 420     m_dc
.SetTextForeground(m_window
->GetForegroundColour()); 
 422     wxString label 
= m_window
->GetLabel(); 
 423     if ( !label
.empty() || bitmap
.Ok() ) 
 425         wxRect rectLabel 
= m_rect
; 
 428             rectLabel
.Inflate(-marginX
, -marginY
); 
 431         wxControl 
*ctrl 
= wxStaticCast(m_window
, wxControl
); 
 433         m_renderer
->DrawButtonLabel(m_dc
, 
 437                                     m_window
->GetStateFlags(), 
 438                                     ctrl
->GetAlignment(), 
 439                                     ctrl
->GetAccelIndex()); 
 443 void wxControlRenderer::DrawFrame() 
 445     m_dc
.SetFont(m_window
->GetFont()); 
 446     m_dc
.SetTextForeground(m_window
->GetForegroundColour()); 
 447     m_dc
.SetTextBackground(m_window
->GetBackgroundColour()); 
 449     wxControl 
*ctrl 
= wxStaticCast(m_window
, wxControl
); 
 451     m_renderer
->DrawFrame(m_dc
, 
 452                           m_window
->GetLabel(), 
 454                           m_window
->GetStateFlags(), 
 455                           ctrl
->GetAlignment(), 
 456                           ctrl
->GetAccelIndex()); 
 459 void wxControlRenderer::DrawButtonBorder() 
 461     int flags 
= m_window
->GetStateFlags(); 
 463     m_renderer
->DrawButtonBorder(m_dc
, m_rect
, flags
, &m_rect
); 
 466     // m_renderer->DrawButtonSurface(m_dc, wxTHEME_BG_COLOUR(m_window), m_rect, flags ); 
 469 void wxControlRenderer::DrawBitmap(const wxBitmap
& bitmap
) 
 471     int style 
= m_window
->GetWindowStyle(); 
 472     DrawBitmap(m_dc
, bitmap
, m_rect
, 
 473                style 
& wxALIGN_MASK
, 
 474                style 
& wxBI_EXPAND 
? wxEXPAND 
: wxSTRETCH_NOT
); 
 478 void wxControlRenderer::DrawBitmap(wxDC 
&dc
, 
 479                                    const wxBitmap
& bitmap
, 
 484     // we may change the bitmap if we stretch it 
 485     wxBitmap bmp 
= bitmap
; 
 489     int width 
= bmp
.GetWidth(), 
 490         height 
= bmp
.GetHeight(); 
 494     if ( stretch 
& wxTILE 
) 
 497         for ( ; x 
< rect
.width
; x 
+= width 
) 
 499             for ( y 
= 0; y 
< rect
.height
; y 
+= height 
) 
 501                 // no need to use mask here as we cover the entire window area 
 502                 dc
.DrawBitmap(bmp
, x
, y
); 
 506     else if ( stretch 
& wxEXPAND 
) 
 508         // stretch bitmap to fill the entire control 
 509         bmp 
= wxBitmap(wxImage(bmp
.ConvertToImage()).Scale(rect
.width
, rect
.height
)); 
 511     else // not stretched, not tiled 
 513         if ( alignment 
& wxALIGN_RIGHT 
) 
 515             x 
= rect
.GetRight() - width
; 
 517         else if ( alignment 
& wxALIGN_CENTRE 
) 
 519             x 
= (rect
.GetLeft() + rect
.GetRight() - width 
+ 1) / 2; 
 521         else // alignment & wxALIGN_LEFT 
 526         if ( alignment 
& wxALIGN_BOTTOM 
) 
 528             y 
= rect
.GetBottom() - height
; 
 530         else if ( alignment 
& wxALIGN_CENTRE_VERTICAL 
) 
 532             y 
= (rect
.GetTop() + rect
.GetBottom() - height 
+ 1) / 2; 
 534         else // alignment & wxALIGN_TOP 
 541     dc
.DrawBitmap(bmp
, x
, y
, true /* use mask */); 
 544 void wxControlRenderer::DrawScrollbar(const wxScrollBar 
*scrollbar
, 
 545                                       int WXUNUSED(thumbPosOld
)) 
 547     // we will only redraw the parts which must be redrawn and not everything 
 548     wxRegion rgnUpdate 
= scrollbar
->GetUpdateRegion(); 
 551         wxRect rectUpdate 
= rgnUpdate
.GetBox(); 
 552         wxLogTrace(_T("scrollbar"), 
 553                    _T("%s redraw: update box is (%d, %d)-(%d, %d)"), 
 554                    scrollbar
->IsVertical() ? _T("vert") : _T("horz"), 
 555                    rectUpdate
.GetLeft(), 
 557                    rectUpdate
.GetRight(), 
 558                    rectUpdate
.GetBottom()); 
 560 #if 0 //def WXDEBUG_SCROLLBAR 
 561         static bool s_refreshDebug 
= false; 
 562         if ( s_refreshDebug 
) 
 564             wxClientDC 
dc(wxConstCast(scrollbar
, wxScrollBar
)); 
 565             dc
.SetBrush(*wxRED_BRUSH
); 
 566             dc
.SetPen(*wxTRANSPARENT_PEN
); 
 567             dc
.DrawRectangle(rectUpdate
); 
 569             // under Unix we use "--sync" X option for this 
 575 #endif // WXDEBUG_SCROLLBAR 
 578     wxOrientation orient 
= scrollbar
->IsVertical() ? wxVERTICAL
 
 582     for ( int nBar 
= 0; nBar 
< 2; nBar
++ ) 
 584         wxScrollBar::Element elem 
= 
 585             (wxScrollBar::Element
)(wxScrollBar::Element_Bar_1 
+ nBar
); 
 587         wxRect rectBar 
= m_renderer
->GetScrollbarRect(scrollbar
, elem
); 
 589         if ( rgnUpdate
.Contains(rectBar
) ) 
 591             wxLogTrace(_T("scrollbar"), 
 592                        _T("drawing bar part %d at (%d, %d)-(%d, %d)"), 
 597                        rectBar
.GetBottom()); 
 599             m_renderer
->DrawScrollbarShaft(m_dc
, 
 602                                            scrollbar
->GetState(elem
)); 
 607     for ( int nArrow 
= 0; nArrow 
< 2; nArrow
++ ) 
 609         wxScrollBar::Element elem 
= 
 610             (wxScrollBar::Element
)(wxScrollBar::Element_Arrow_Line_1 
+ nArrow
); 
 612         wxRect rectArrow 
= m_renderer
->GetScrollbarRect(scrollbar
, elem
); 
 613         if ( rgnUpdate
.Contains(rectArrow
) ) 
 615             wxLogTrace(_T("scrollbar"), 
 616                        _T("drawing arrow %d at (%d, %d)-(%d, %d)"), 
 620                        rectArrow
.GetRight(), 
 621                        rectArrow
.GetBottom()); 
 623             scrollbar
->GetArrows().DrawArrow
 
 625                 (wxScrollArrows::Arrow
)nArrow
, 
 628                 true // draw a scrollbar arrow, not just an arrow 
 633     // TODO: support for page arrows 
 636     wxScrollBar::Element elem 
= wxScrollBar::Element_Thumb
; 
 637     wxRect rectThumb 
= m_renderer
->GetScrollbarRect(scrollbar
, elem
); 
 638     if ( rectThumb
.width 
&& rectThumb
.height 
&& rgnUpdate
.Contains(rectThumb
) ) 
 640         wxLogTrace(_T("scrollbar"), 
 641                    _T("drawing thumb at (%d, %d)-(%d, %d)"), 
 644                    rectThumb
.GetRight(), 
 645                    rectThumb
.GetBottom()); 
 647         m_renderer
->DrawScrollbarThumb(m_dc
, 
 650                                        scrollbar
->GetState(elem
)); 
 654 void wxControlRenderer::DrawLine(wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
) 
 656     wxASSERT_MSG( x1 
== x2 
|| y1 
== y2
, 
 657                   _T("line must be either horizontal or vertical") ); 
 660         m_renderer
->DrawVerticalLine(m_dc
, x1
, y1
, y2
); 
 662         m_renderer
->DrawHorizontalLine(m_dc
, y1
, x1
, x2
); 
 667 void wxControlRenderer::DrawItems(const wxListBox 
*lbox
, 
 668                                   size_t itemFirst
, size_t itemLast
) 
 670     DoDrawItems(lbox
, itemFirst
, itemLast
); 
 673 void wxControlRenderer::DoDrawItems(const wxListBox 
*lbox
, 
 674                                     size_t itemFirst
, size_t itemLast
, 
 675 #if wxUSE_CHECKLISTBOX 
 678                                     bool WXUNUSED(isCheckLbox
)) 
 681     // prepare for the drawing: calc the initial position 
 682     wxCoord lineHeight 
= lbox
->GetLineHeight(); 
 684     // note that SetClippingRegion() needs the physical (unscrolled) 
 685     // coordinates while we use the logical (scrolled) ones for the drawing 
 688     wxSize size 
= lbox
->GetClientSize(); 
 690     rect
.height 
= size
.y
; 
 692     // keep the text inside the client rect or we will overwrite the vertical 
 693     // scrollbar for the long strings 
 694     m_dc
.SetClippingRegion(rect
.x
, rect
.y
, rect
.width 
+ 1, rect
.height 
+ 1); 
 696     // adjust the rect position now 
 697     lbox
->CalcScrolledPosition(rect
.x
, rect
.y
, &rect
.x
, &rect
.y
); 
 698     rect
.y 
+= itemFirst
*lineHeight
; 
 699     rect
.height 
= lineHeight
; 
 701     // the rect should go to the right visible border so adjust the width if x 
 702     // is shifted (rightmost point should stay the same) 
 703     rect
.width 
-= rect
.x
; 
 705     // we'll keep the text colour unchanged 
 706     m_dc
.SetTextForeground(lbox
->GetForegroundColour()); 
 708     // an item should have the focused rect only when the lbox has focus, so 
 709     // make sure that we never set wxCONTROL_FOCUSED flag if it doesn't 
 710     int itemCurrent 
= wxWindow::FindFocus() == (wxWindow 
*)lbox 
// cast needed 
 711                         ? lbox
->GetCurrentItem() 
 713     for ( size_t n 
= itemFirst
; n 
< itemLast
; n
++ ) 
 716         if ( (int)n 
== itemCurrent 
) 
 717             flags 
|= wxCONTROL_FOCUSED
; 
 718         if ( lbox
->IsSelected(n
) ) 
 719             flags 
|= wxCONTROL_SELECTED
; 
 721 #if wxUSE_CHECKLISTBOX 
 724             wxCheckListBox 
*checklstbox 
= wxStaticCast(lbox
, wxCheckListBox
); 
 725             if ( checklstbox
->IsChecked(n
) ) 
 726                 flags 
|= wxCONTROL_CHECKED
; 
 728             m_renderer
->DrawCheckItem(m_dc
, lbox
->GetString(n
), 
 734 #endif // wxUSE_CHECKLISTBOX 
 736             m_renderer
->DrawItem(m_dc
, lbox
->GetString(n
), rect
, flags
); 
 739         rect
.y 
+= lineHeight
; 
 743 #endif // wxUSE_LISTBOX 
 745 #if wxUSE_CHECKLISTBOX 
 747 void wxControlRenderer::DrawCheckItems(const wxCheckListBox 
*lbox
, 
 748                                        size_t itemFirst
, size_t itemLast
) 
 750     DoDrawItems(lbox
, itemFirst
, itemLast
, true); 
 753 #endif // wxUSE_CHECKLISTBOX 
 757 void wxControlRenderer::DrawProgressBar(const wxGauge 
*gauge
) 
 760     m_dc
.SetBrush(wxBrush(m_window
->GetBackgroundColour(), wxSOLID
)); 
 761     m_dc
.SetPen(*wxTRANSPARENT_PEN
); 
 762     m_dc
.DrawRectangle(m_rect
); 
 764     int max 
= gauge
->GetRange(); 
 771     // calc the filled rect 
 772     int pos 
= gauge
->GetValue(); 
 773     int left 
= max 
- pos
; 
 775     wxRect rect 
= m_rect
; 
 776     rect
.Deflate(1); // FIXME this depends on the border width 
 778     wxColour col 
= m_window
->UseFgCol() ? m_window
->GetForegroundColour() 
 779                                         : wxTHEME_COLOUR(GAUGE
); 
 780     m_dc
.SetBrush(wxBrush(col
, wxSOLID
)); 
 782     if ( gauge
->IsSmooth() ) 
 784         // just draw the rectangle in one go 
 785         if ( gauge
->IsVertical() ) 
 787             // vert bars grow from bottom to top 
 788             wxCoord dy 
= ((rect
.height 
- 1) * left
) / max
; 
 794             // grow from left to right 
 795             rect
.width 
-= ((rect
.width 
- 1) * left
) / max
; 
 798         m_dc
.DrawRectangle(rect
); 
 802         wxSize sizeStep 
= m_renderer
->GetProgressBarStep(); 
 803         int step 
= gauge
->IsVertical() ? sizeStep
.y 
: sizeStep
.x
; 
 805         // we divide by it below! 
 806         wxCHECK_RET( step
, _T("invalid wxGauge step") ); 
 808         // round up to make the progress appear to start faster 
 809         int lenTotal 
= gauge
->IsVertical() ? rect
.height 
: rect
.width
; 
 810         int steps 
= ((lenTotal 
+ step 
- 1) * pos
) / (max 
* step
); 
 812         // calc the coords of one small rect 
 815         if ( gauge
->IsVertical() ) 
 817             // draw from bottom to top: so first set y to the bottom 
 818             rect
.y 
+= rect
.height 
- 1; 
 820             // then adjust the height 
 823             // and then adjust y again to be what it should for the first rect 
 824             rect
.y 
-= rect
.height
; 
 829             // remember that this will be the coord which will change 
 837             // don't leave 2 empty pixels in the beginning 
 847         for ( int n 
= 0; n 
< steps
; n
++ ) 
 849             wxRect rectSegment 
= rect
; 
 850             rectSegment
.Deflate(dx
, dy
); 
 852             m_dc
.DrawRectangle(rectSegment
); 
 857                 // this can only happen for the last step of vertical gauge 
 858                 rect
.height 
= *px 
- step 
- 1; 
 861             else if ( *px 
> lenTotal 
- step 
) 
 863                 // this can only happen for the last step of horizontal gauge 
 864                 rect
.width 
= lenTotal 
- *px 
- 1; 
 870 #endif // wxUSE_GAUGE