1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        univ/renderer.cpp 
   3 // Purpose:     wxControlRenderer implementation 
   4 // Author:      Vadim Zeitlin 
   8 // Copyright:   (c) 2000 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> 
   9 // Licence:     wxWindows license 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // =========================================================================== 
  14 // =========================================================================== 
  16 // --------------------------------------------------------------------------- 
  18 // --------------------------------------------------------------------------- 
  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" 
  42 #include "wx/univ/theme.h" 
  43 #include "wx/univ/renderer.h" 
  44 #include "wx/univ/colschem.h" 
  50 // ============================================================================ 
  52 // ============================================================================ 
  54 // ---------------------------------------------------------------------------- 
  55 // wxRenderer: drawing helpers 
  56 // ---------------------------------------------------------------------------- 
  58 void wxRenderer::StandardDrawFrame(wxDC
& dc
, 
  59                                    const wxRect
& rectFrame
, 
  60                                    const wxRect
& rectLabel
) 
  62     // draw left, bottom and right lines entirely 
  63     DrawVerticalLine(dc
, rectFrame
.GetLeft(), 
  64                      rectFrame
.GetTop(), rectFrame
.GetBottom() - 2); 
  65     DrawHorizontalLine(dc
, rectFrame
.GetBottom() - 1, 
  66                        rectFrame
.GetLeft(), rectFrame
.GetRight()); 
  67     DrawVerticalLine(dc
, rectFrame
.GetRight() - 1, 
  68                      rectFrame
.GetTop(), rectFrame
.GetBottom() - 1); 
  70     // and 2 parts of the top line 
  71     DrawHorizontalLine(dc
, rectFrame
.GetTop(), 
  72                        rectFrame
.GetLeft() + 1, rectLabel
.GetLeft()); 
  73     DrawHorizontalLine(dc
, rectFrame
.GetTop(), 
  74                        rectLabel
.GetRight(), rectFrame
.GetRight() - 2); 
  78 void wxRenderer::StandardDrawTextLine(wxDC
& dc
, 
  81                                       int selStart
, int selEnd
, 
  84     if ( (selStart 
== -1) || !(flags 
& wxCONTROL_FOCUSED
) ) 
  87         dc
.DrawText(text
, rect
.x
, rect
.y
); 
  89     else // we have selection 
  94         // draw the part before selection 
  95         wxString 
s(text
, (size_t)selStart
); 
  98             dc
.DrawText(s
, x
, rect
.y
); 
 100             dc
.GetTextExtent(s
, &width
, NULL
); 
 104         // draw the selection itself 
 105         s 
= wxString(text
.c_str() + selStart
, text
.c_str() + selEnd
); 
 108             wxColour colFg 
= dc
.GetTextForeground(), 
 109                      colBg 
= dc
.GetTextBackground(); 
 110             dc
.SetTextForeground(wxTHEME_COLOUR(HIGHLIGHT_TEXT
)); 
 111             dc
.SetTextBackground(wxTHEME_COLOUR(HIGHLIGHT
)); 
 112             dc
.SetBackgroundMode(wxSOLID
); 
 114             dc
.DrawText(s
, x
, rect
.y
); 
 115             dc
.GetTextExtent(s
, &width
, NULL
); 
 118             dc
.SetBackgroundMode(wxTRANSPARENT
); 
 119             dc
.SetTextBackground(colBg
); 
 120             dc
.SetTextForeground(colFg
); 
 123         // draw the final part 
 124         s 
= text
.c_str() + selEnd
; 
 127             dc
.DrawText(s
, x
, rect
.y
); 
 132 // ---------------------------------------------------------------------------- 
 133 // wxRenderer: scrollbar geometry 
 134 // ---------------------------------------------------------------------------- 
 137 void wxRenderer::StandardScrollBarThumbSize(wxCoord length
, 
 144     // the thumb can't be made less than this number of pixels 
 145     static const wxCoord thumbMinWidth 
= 8; // FIXME: should be configurable 
 147     *thumbStart 
= (length
*thumbPos
) / range
; 
 148     *thumbEnd 
= (length
*(thumbPos 
+ thumbSize
)) / range
; 
 150     if ( *thumbEnd 
- *thumbStart 
< thumbMinWidth 
) 
 152         // adjust the end if possible 
 153         if ( *thumbStart 
<= length 
- thumbMinWidth 
) 
 155             // yes, just make it wider 
 156             *thumbEnd 
= *thumbStart 
+ thumbMinWidth
; 
 158         else // it is at the bottom of the scrollbar 
 160             // so move it a bit up 
 161             *thumbStart 
= length 
- thumbMinWidth
; 
 168 wxRect 
wxRenderer::StandardGetScrollbarRect(const wxScrollBar 
*scrollbar
, 
 169                                             wxScrollBar::Element elem
, 
 171                                             const wxSize
& sizeArrow
) 
 173     if ( thumbPos 
== -1 ) 
 175         thumbPos 
= scrollbar
->GetThumbPosition(); 
 178     wxSize sizeTotal 
= scrollbar
->GetClientSize(); 
 179     wxCoord 
*start
, *width
, length
, arrow
; 
 181     if ( scrollbar
->IsVertical() ) 
 184         rect
.width 
= sizeTotal
.x
; 
 185         length 
= sizeTotal
.y
; 
 187         width 
= &rect
.height
; 
 193         rect
.height 
= sizeTotal
.y
; 
 194         length 
= sizeTotal
.x
; 
 202         case wxScrollBar::Element_Arrow_Line_1
: 
 207         case wxScrollBar::Element_Arrow_Line_2
: 
 208             *start 
= length 
- arrow
; 
 212         case wxScrollBar::Element_Arrow_Page_1
: 
 213         case wxScrollBar::Element_Arrow_Page_2
: 
 214             // we don't have them at all 
 217         case wxScrollBar::Element_Thumb
: 
 218         case wxScrollBar::Element_Bar_1
: 
 219         case wxScrollBar::Element_Bar_2
: 
 220             // we need to calculate the thumb position - do it 
 223                 wxCoord thumbStart
, thumbEnd
; 
 224                 int range 
= scrollbar
->GetRange(); 
 232                     StandardScrollBarThumbSize(length
, 
 234                                                scrollbar
->GetThumbSize(), 
 240                 if ( elem 
== wxScrollBar::Element_Thumb 
) 
 243                     *width 
= thumbEnd 
- thumbStart
; 
 245                 else if ( elem 
== wxScrollBar::Element_Bar_1 
) 
 250                 else // elem == wxScrollBar::Element_Bar_2 
 253                     *width 
= length 
- thumbEnd
; 
 256                 // everything is relative to the start of the shaft so far 
 261         case wxScrollBar::Element_Max
: 
 263             wxFAIL_MSG( _T("unknown scrollbar element") ); 
 270 wxCoord 
wxRenderer::StandardScrollBarSize(const wxScrollBar 
*scrollbar
, 
 271                                           const wxSize
& sizeArrowSB
) 
 273     wxCoord sizeArrow
, sizeTotal
; 
 274     if ( scrollbar
->GetWindowStyle() & wxVERTICAL 
) 
 276         sizeArrow 
= sizeArrowSB
.y
; 
 277         sizeTotal 
= scrollbar
->GetSize().y
; 
 281         sizeArrow 
= sizeArrowSB
.x
; 
 282         sizeTotal 
= scrollbar
->GetSize().x
; 
 285     return sizeTotal 
- 2*sizeArrow
; 
 289 wxCoord 
wxRenderer::StandardScrollbarToPixel(const wxScrollBar 
*scrollbar
, 
 291                                              const wxSize
& sizeArrow
) 
 293     int range 
= scrollbar
->GetRange(); 
 296         // the only valid position anyhow 
 300     if ( thumbPos 
== -1 ) 
 302         // by default use the current thumb position 
 303         thumbPos 
= scrollbar
->GetThumbPosition(); 
 306     return ( thumbPos
*StandardScrollBarSize(scrollbar
, sizeArrow
) ) / range
 
 307              + (scrollbar
->IsVertical() ? sizeArrow
.y 
: sizeArrow
.x
); 
 311 int wxRenderer::StandardPixelToScrollbar(const wxScrollBar 
*scrollbar
, 
 313                                          const wxSize
& sizeArrow
) 
 315     return ( (coord 
- (scrollbar
->IsVertical() ? sizeArrow
.y 
: sizeArrow
.x
)) * 
 316                scrollbar
->GetRange() ) / 
 317                StandardScrollBarSize(scrollbar
, sizeArrow
); 
 321 wxHitTest 
wxRenderer::StandardHitTestScrollbar(const wxScrollBar 
*scrollbar
, 
 323                                                const wxSize
& sizeArrowSB
) 
 325     // we only need to work with either x or y coord depending on the 
 326     // orientation, choose one (but still check the other one to verify if the 
 327     // mouse is in the window at all) 
 328     wxCoord coord
, sizeArrow
, sizeTotal
; 
 329     wxSize size 
= scrollbar
->GetSize(); 
 330     if ( scrollbar
->GetWindowStyle() & wxVERTICAL 
) 
 332         if ( pt
.x 
< 0 || pt
.x 
> size
.x 
) 
 336         sizeArrow 
= sizeArrowSB
.y
; 
 341         if ( pt
.y 
< 0 || pt
.y 
> size
.y 
) 
 345         sizeArrow 
= sizeArrowSB
.x
; 
 349     // test for the arrows first as it's faster 
 350     if ( coord 
< 0 || coord 
> sizeTotal 
) 
 354     else if ( coord 
< sizeArrow 
) 
 356         return wxHT_SCROLLBAR_ARROW_LINE_1
; 
 358     else if ( coord 
> sizeTotal 
- sizeArrow 
) 
 360         return wxHT_SCROLLBAR_ARROW_LINE_2
; 
 364         // calculate the thumb position in pixels 
 365         sizeTotal 
-= 2*sizeArrow
; 
 366         wxCoord thumbStart
, thumbEnd
; 
 367         int range 
= scrollbar
->GetRange(); 
 370             // clicking the scrollbar without range has no effect 
 375             StandardScrollBarThumbSize(sizeTotal
, 
 376                                        scrollbar
->GetThumbPosition(), 
 377                                        scrollbar
->GetThumbSize(), 
 383         // now compare with the thumb position 
 385         if ( coord 
< thumbStart 
) 
 386             return wxHT_SCROLLBAR_BAR_1
; 
 387         else if ( coord 
> thumbEnd 
) 
 388             return wxHT_SCROLLBAR_BAR_2
; 
 390             return wxHT_SCROLLBAR_THUMB
; 
 394 wxRenderer::~wxRenderer() 
 398 // ---------------------------------------------------------------------------- 
 400 // ---------------------------------------------------------------------------- 
 402 wxControlRenderer::wxControlRenderer(wxWindow 
*window
, 
 404                                      wxRenderer 
*renderer
) 
 408     m_renderer 
= renderer
; 
 410     wxSize size 
= m_window
->GetClientSize(); 
 413     m_rect
.width 
= size
.x
; 
 414     m_rect
.height 
= size
.y
; 
 417 void wxControlRenderer::DrawLabel(const wxBitmap
& bitmap
, 
 418                                   wxCoord marginX
, wxCoord marginY
) 
 420     m_dc
.SetFont(m_window
->GetFont()); 
 421     m_dc
.SetTextForeground(m_window
->GetForegroundColour()); 
 423     wxString label 
= m_window
->GetLabel(); 
 424     if ( !label
.empty() || bitmap
.Ok() ) 
 426         wxRect rectLabel 
= m_rect
; 
 429             rectLabel
.Inflate(-marginX
, -marginY
); 
 432         wxControl 
*ctrl 
= wxStaticCast(m_window
, wxControl
); 
 434         m_renderer
->DrawButtonLabel(m_dc
, 
 438                                     m_window
->GetStateFlags(), 
 439                                     ctrl
->GetAlignment(), 
 440                                     ctrl
->GetAccelIndex()); 
 444 void wxControlRenderer::DrawFrame() 
 446     m_dc
.SetFont(m_window
->GetFont()); 
 447     m_dc
.SetTextForeground(m_window
->GetForegroundColour()); 
 448     m_dc
.SetTextBackground(m_window
->GetBackgroundColour()); 
 450     wxControl 
*ctrl 
= wxStaticCast(m_window
, wxControl
); 
 452     m_renderer
->DrawFrame(m_dc
, 
 453                           m_window
->GetLabel(), 
 455                           m_window
->GetStateFlags(), 
 456                           ctrl
->GetAlignment(), 
 457                           ctrl
->GetAccelIndex()); 
 460 void wxControlRenderer::DrawButtonBorder() 
 462     int flags 
= m_window
->GetStateFlags(); 
 464     m_renderer
->DrawButtonBorder(m_dc
, m_rect
, flags
, &m_rect
); 
 466     m_renderer
->DrawBackground(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 
= wxImage(bmp
).Scale(rect
.width
, rect
.height
).ConvertToBitmap(); 
 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
, 
 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
, 
 677     // prepare for the drawing: calc the initial position 
 678     wxCoord lineHeight 
= lbox
->GetLineHeight(); 
 680     // note that SetClippingRegion() needs the physical (unscrolled) 
 681     // coordinates while we use the logical (scrolled) ones for the drawing 
 684     wxSize size 
= lbox
->GetClientSize(); 
 686     rect
.height 
= size
.y
; 
 688     // keep the text inside the client rect or we will overwrite the vertical 
 689     // scrollbar for the long strings 
 690     m_dc
.SetClippingRegion(rect
.x
, rect
.y
, rect
.width 
+ 1, rect
.height 
+ 1); 
 692     // adjust the rect position now 
 693     lbox
->CalcScrolledPosition(rect
.x
, rect
.y
, &rect
.x
, &rect
.y
); 
 694     rect
.y 
+= itemFirst
*lineHeight
; 
 695     rect
.height 
= lineHeight
; 
 697     // the rect should go to the right visible border so adjust the width if x 
 698     // is shifted (rightmost point should stay the same) 
 699     rect
.width 
-= rect
.x
; 
 701     // we'll keep the text colour unchanged 
 702     m_dc
.SetTextForeground(lbox
->GetForegroundColour()); 
 704     // an item should have the focused rect only when the lbox has focus, so 
 705     // make sure that we never set wxCONTROL_FOCUSED flag if it doesn't 
 706     int itemCurrent 
= wxWindow::FindFocus() == (wxWindow 
*)lbox 
// cast needed 
 707                         ? lbox
->GetCurrentItem() 
 709     for ( size_t n 
= itemFirst
; n 
< itemLast
; n
++ ) 
 712         if ( (int)n 
== itemCurrent 
) 
 713             flags 
|= wxCONTROL_FOCUSED
; 
 714         if ( lbox
->IsSelected(n
) ) 
 715             flags 
|= wxCONTROL_SELECTED
; 
 717 #if wxUSE_CHECKLISTBOX 
 720             wxCheckListBox 
*checklstbox 
= wxStaticCast(lbox
, wxCheckListBox
); 
 721             if ( checklstbox
->IsChecked(n
) ) 
 722                 flags 
|= wxCONTROL_CHECKED
; 
 724             m_renderer
->DrawCheckItem(m_dc
, lbox
->GetString(n
), 
 730 #endif // wxUSE_CHECKLISTBOX 
 732             m_renderer
->DrawItem(m_dc
, lbox
->GetString(n
), rect
, flags
); 
 735         rect
.y 
+= lineHeight
; 
 739 #endif // wxUSE_LISTBOX 
 741 #if wxUSE_CHECKLISTBOX 
 743 void wxControlRenderer::DrawCheckItems(const wxCheckListBox 
*lbox
, 
 744                                        size_t itemFirst
, size_t itemLast
) 
 746     DoDrawItems(lbox
, itemFirst
, itemLast
, TRUE
); 
 749 #endif // wxUSE_CHECKLISTBOX 
 753 void wxControlRenderer::DrawProgressBar(const wxGauge 
*gauge
) 
 756     m_dc
.SetBrush(wxBrush(m_window
->GetBackgroundColour(), wxSOLID
)); 
 757     m_dc
.SetPen(*wxTRANSPARENT_PEN
); 
 758     m_dc
.DrawRectangle(m_rect
); 
 760     int max 
= gauge
->GetRange(); 
 767     // calc the filled rect 
 768     int pos 
= gauge
->GetValue(); 
 769     int left 
= max 
- pos
; 
 771     wxRect rect 
= m_rect
; 
 772     rect
.Deflate(1); // FIXME this depends on the border width 
 774     m_dc
.SetBrush(wxBrush(m_window
->GetForegroundColour(), wxSOLID
)); 
 776     if ( gauge
->IsSmooth() ) 
 778         // just draw the rectangle in one go 
 779         if ( gauge
->IsVertical() ) 
 781             // vert bars grow from bottom to top 
 782             wxCoord dy 
= ((rect
.height 
- 1) * left
) / max
; 
 788             // grow from left to right 
 789             rect
.width 
-= ((rect
.width 
- 1) * left
) / max
; 
 792         m_dc
.DrawRectangle(rect
); 
 796         wxSize sizeStep 
= m_renderer
->GetProgressBarStep(); 
 797         int step 
= gauge
->IsVertical() ? sizeStep
.y 
: sizeStep
.x
; 
 799         // we divide by it below! 
 800         wxCHECK_RET( step
, _T("invalid wxGauge step") ); 
 802         // round up to make the progress appear to start faster 
 803         int lenTotal 
= gauge
->IsVertical() ? rect
.height 
: rect
.width
; 
 804         int steps 
= ((lenTotal 
+ step 
- 1) * pos
) / (max 
* step
); 
 806         // calc the coords of one small rect 
 808         if ( gauge
->IsVertical() ) 
 810             // draw from bottom to top: so first set y to the bottom 
 811             rect
.y 
+= rect
.height 
- 1; 
 813             // then adjust the height 
 816             // and then adjust y again to be what it should for the first rect 
 817             rect
.y 
-= rect
.height
; 
 822             // remember that this will be the coord which will change 
 830             // don't leave 2 empty pixels in the beginning 
 840         for ( int n 
= 0; n 
< steps
; n
++ ) 
 842             wxRect rectSegment 
= rect
; 
 843             rectSegment
.Deflate(dx
, dy
); 
 845             m_dc
.DrawRectangle(rectSegment
); 
 850                 // this can only happen for the last step of vertical gauge 
 851                 rect
.height 
= *px 
- step 
- 1; 
 854             else if ( *px 
> lenTotal 
- step 
) 
 856                 // this can only happen for the last step of horizontal gauge 
 857                 rect
.width 
= lenTotal 
- *px 
- 1; 
 863 #endif // wxUSE_GAUGE