1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/univ/stdrend.cpp 
   3 // Purpose:     implementation of wxStdRenderer 
   4 // Author:      Vadim Zeitlin 
   7 // Copyright:   (c) 2006 Vadim Zeitlin <vadim@wxwindows.org> 
   8 // Licence:     wxWindows licence 
   9 /////////////////////////////////////////////////////////////////////////////// 
  11 // ============================================================================ 
  13 // ============================================================================ 
  15 // ---------------------------------------------------------------------------- 
  17 // ---------------------------------------------------------------------------- 
  19 // for compilers that support precompilation, includes "wx.h". 
  20 #include "wx/wxprec.h" 
  27     #include "wx/settings.h" 
  30     #include "wx/statusbr.h" 
  31     #include "wx/toplevel.h" 
  34 #include "wx/univ/stdrend.h" 
  35 #include "wx/univ/colschem.h" 
  37 // ---------------------------------------------------------------------------- 
  39 // ---------------------------------------------------------------------------- 
  41 static const int FRAME_TITLEBAR_HEIGHT             
= 18; 
  42 static const int FRAME_BUTTON_WIDTH                
= 16; 
  43 static const int FRAME_BUTTON_HEIGHT               
= 14; 
  45 // the margin between listbox item text and its rectangle 
  46 static const int ITEM_MARGIN 
= 1; 
  48 // ============================================================================ 
  49 // wxStdRenderer implementation 
  50 // ============================================================================ 
  52 // ---------------------------------------------------------------------------- 
  54 // ---------------------------------------------------------------------------- 
  56 wxStdRenderer::wxStdRenderer(const wxColourScheme 
*scheme
) 
  59     m_penBlack 
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
)); 
  60     m_penDarkGrey 
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_OUT
)); 
  61     m_penLightGrey 
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
)); 
  62     m_penHighlight 
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
)); 
  64     m_titlebarFont 
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
); 
  65     m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
); 
  68 // ---------------------------------------------------------------------------- 
  70 // ---------------------------------------------------------------------------- 
  73 wxStdRenderer::DrawSolidRect(wxDC
& dc
, const wxColour
& col
, const wxRect
& rect
) 
  75     wxBrush 
brush(col
, wxSOLID
); 
  77     dc
.SetPen(*wxTRANSPARENT_PEN
); 
  78     dc
.DrawRectangle(rect
); 
  81 void wxStdRenderer::DrawRect(wxDC
& dc
, wxRect 
*rect
, const wxPen
& pen
) 
  85     dc
.SetBrush(*wxTRANSPARENT_BRUSH
); 
  86     dc
.DrawRectangle(*rect
); 
  92 void wxStdRenderer::DrawShadedRect(wxDC
& dc
, wxRect 
*rect
, 
  93                                    const wxPen
& pen1
, const wxPen
& pen2
) 
  97     dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(), 
  98                 rect
->GetLeft(), rect
->GetBottom()); 
  99     dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(), 
 100                 rect
->GetRight(), rect
->GetTop()); 
 102     dc
.DrawLine(rect
->GetRight(), rect
->GetTop(), 
 103                 rect
->GetRight(), rect
->GetBottom()); 
 104     dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(), 
 105                 rect
->GetRight() + 1, rect
->GetBottom()); 
 111 // ---------------------------------------------------------------------------- 
 112 // translate various flags into corresponding renderer constants 
 113 // ---------------------------------------------------------------------------- 
 116 void wxStdRenderer::GetIndicatorsFromFlags(int flags
, 
 117                                            IndicatorState
& state
, 
 118                                            IndicatorStatus
& status
) 
 120     if ( flags 
& wxCONTROL_SELECTED 
) 
 121         state 
= flags 
& wxCONTROL_DISABLED 
? IndicatorState_SelectedDisabled
 
 122                                            : IndicatorState_Selected
; 
 123     else if ( flags 
& wxCONTROL_DISABLED 
) 
 124         state 
= IndicatorState_Disabled
; 
 125     else if ( flags 
& wxCONTROL_PRESSED 
) 
 126         state 
= IndicatorState_Pressed
; 
 128         state 
= IndicatorState_Normal
; 
 130     status 
= flags 
& wxCONTROL_CHECKED 
? IndicatorStatus_Checked
 
 131                                        : flags 
& wxCONTROL_UNDETERMINED
 
 132                                             ? IndicatorStatus_Undetermined
 
 133                                             : IndicatorStatus_Unchecked
; 
 137 wxStdRenderer::ArrowDirection 
wxStdRenderer::GetArrowDirection(wxDirection dir
) 
 154             wxFAIL_MSG(wxT("unknown arrow direction")); 
 160 // ---------------------------------------------------------------------------- 
 162 // ---------------------------------------------------------------------------- 
 164 void wxStdRenderer::DrawBackground(wxDC
& dc
, 
 178         colBg 
= m_scheme
->GetBackground(window
); 
 182         colBg 
= wxSCHEME_COLOUR(m_scheme
, CONTROL
); 
 185     DrawSolidRect(dc
, colBg
, rect
); 
 189 void wxStdRenderer::DrawButtonSurface(wxDC
& dc
, 
 194     DrawBackground(dc
, col
, rect
, flags
); 
 197 // ---------------------------------------------------------------------------- 
 199 // ---------------------------------------------------------------------------- 
 202 wxStdRenderer::DrawFocusRect(wxWindow
* WXUNUSED(win
), wxDC
& dc
, const wxRect
& rect
, int WXUNUSED(flags
)) 
 204     // draw the pixels manually because the "dots" in wxPen with wxDOT style 
 205     // may be short traits and not really dots 
 207     // note that to behave in the same manner as DrawRect(), we must exclude 
 208     // the bottom and right borders from the rectangle 
 209     wxCoord x1 
= rect
.GetLeft(), 
 211             x2 
= rect
.GetRight(), 
 212             y2 
= rect
.GetBottom(); 
 214     dc
.SetPen(m_penBlack
); 
 216     // this seems to be closer than what Windows does than wxINVERT although 
 217     // I'm still not sure if it's correct 
 218     dc
.SetLogicalFunction(wxAND_REVERSE
); 
 221     for ( z 
= x1 
+ 1; z 
< x2
; z 
+= 2 ) 
 222         dc
.DrawPoint(z
, rect
.GetTop()); 
 224     wxCoord shift 
= z 
== x2 
? 0 : 1; 
 225     for ( z 
= y1 
+ shift
; z 
< y2
; z 
+= 2 ) 
 228     shift 
= z 
== y2 
? 0 : 1; 
 229     for ( z 
= x2 
- shift
; z 
> x1
; z 
-= 2 ) 
 232     shift 
= z 
== x1 
? 0 : 1; 
 233     for ( z 
= y2 
- shift
; z 
> y1
; z 
-= 2 ) 
 236     dc
.SetLogicalFunction(wxCOPY
); 
 239 void wxStdRenderer::DrawLabel(wxDC
& dc
, 
 240                               const wxString
& label
, 
 247     DrawButtonLabel(dc
, label
, wxNullBitmap
, rect
, flags
, 
 248                     alignment
, indexAccel
, rectBounds
); 
 251 void wxStdRenderer::DrawButtonLabel(wxDC
& dc
, 
 252                                     const wxString
& label
, 
 253                                     const wxBitmap
& image
, 
 260     wxDCTextColourChanger 
clrChanger(dc
); 
 262     wxRect rectLabel 
= rect
; 
 263     if ( !label
.empty() && (flags 
& wxCONTROL_DISABLED
) ) 
 265         if ( flags 
& wxCONTROL_PRESSED 
) 
 267             // shift the label if a button is pressed 
 268             rectLabel
.Offset(1, 1); 
 271         // draw shadow of the text 
 272         clrChanger
.Set(m_penHighlight
.GetColour()); 
 273         wxRect rectShadow 
= rect
; 
 274         rectShadow
.Offset(1, 1); 
 275         dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
); 
 277         // make the main label text grey 
 278         clrChanger
.Set(m_penDarkGrey
.GetColour()); 
 280         if ( flags 
& wxCONTROL_FOCUSED 
) 
 282             // leave enough space for the focus rect 
 283             rectLabel
.Inflate(-2); 
 287     dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
); 
 289     if ( !label
.empty() && (flags 
& wxCONTROL_FOCUSED
) ) 
 291         rectLabel
.Inflate(-1); 
 293         DrawFocusRect(NULL
, dc
, rectLabel
); 
 297 // ---------------------------------------------------------------------------- 
 299 // ---------------------------------------------------------------------------- 
 302    We implement standard-looking 3D borders which have the following appearance: 
 306    WWWWWWWWWWWWWWWWWWWWWWB 
 307    WHHHHHHHHHHHHHHHHHHHHGB 
 308    WH                   GB  W = white       (HILIGHT) 
 309    WH                   GB  H = light grey  (LIGHT) 
 310    WH                   GB  G = dark grey   (SHADOI) 
 311    WH                   GB  B = black       (DKSHADOI) 
 314    WGGGGGGGGGGGGGGGGGGGGGB 
 315    BBBBBBBBBBBBBBBBBBBBBBB 
 317    The sunken border looks like this: 
 319    GGGGGGGGGGGGGGGGGGGGGGW 
 320    GBBBBBBBBBBBBBBBBBBBBHW 
 327    GHHHHHHHHHHHHHHHHHHHHHW 
 328    WWWWWWWWWWWWWWWWWWWWWWW 
 330    The static border (used for the controls which don't get focus) is like 
 333    GGGGGGGGGGGGGGGGGGGGGGW 
 341    WWWWWWWWWWWWWWWWWWWWWWW 
 343    The most complicated is the double border which is a combination of special 
 344    "anti-sunken" border and an extra border inside it: 
 346    HHHHHHHHHHHHHHHHHHHHHHB 
 347    HWWWWWWWWWWWWWWWWWWWWGB 
 348    HWHHHHHHHHHHHHHHHHHHHGB 
 353    HWHHHHHHHHHHHHHHHHHHHGB 
 354    HGGGGGGGGGGGGGGGGGGGGGB 
 355    BBBBBBBBBBBBBBBBBBBBBBB 
 357    And the simple border is, well, simple: 
 359    BBBBBBBBBBBBBBBBBBBBBBB 
 368    BBBBBBBBBBBBBBBBBBBBBBB 
 371 void wxStdRenderer::DrawRaisedBorder(wxDC
& dc
, wxRect 
*rect
) 
 373     DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
); 
 374     DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
); 
 377 void wxStdRenderer::DrawSunkenBorder(wxDC
& dc
, wxRect 
*rect
) 
 379     DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
); 
 380     DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
); 
 383 void wxStdRenderer::DrawAntiSunkenBorder(wxDC
& dc
, wxRect 
*rect
) 
 385     DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
); 
 386     DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
); 
 389 void wxStdRenderer::DrawBoxBorder(wxDC
& dc
, wxRect 
*rect
) 
 391     DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
); 
 392     DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
); 
 395 void wxStdRenderer::DrawStaticBorder(wxDC
& dc
, wxRect 
*rect
) 
 397     DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
); 
 400 void wxStdRenderer::DrawExtraBorder(wxDC
& dc
, wxRect 
*rect
) 
 402     DrawRect(dc
, rect
, m_penLightGrey
); 
 405 void wxStdRenderer::DrawBorder(wxDC
& dc
, 
 407                                const wxRect
& rectTotal
, 
 411     wxRect rect 
= rectTotal
; 
 415         case wxBORDER_SUNKEN
: 
 417             DrawSunkenBorder(dc
, &rect
); 
 420         // wxBORDER_DOUBLE and wxBORDER_THEME are currently the same value. 
 422         case wxBORDER_DOUBLE
: 
 423             DrawAntiSunkenBorder(dc
, &rect
); 
 424             DrawExtraBorder(dc
, &rect
); 
 428         case wxBORDER_STATIC
: 
 429             DrawStaticBorder(dc
, &rect
); 
 432         case wxBORDER_RAISED
: 
 433             DrawRaisedBorder(dc
, &rect
); 
 436         case wxBORDER_SIMPLE
: 
 437             DrawRect(dc
, &rect
, m_penBlack
); 
 441             wxFAIL_MSG(wxT("unknown border type")); 
 444         case wxBORDER_DEFAULT
: 
 453 wxRect 
wxStdRenderer::GetBorderDimensions(wxBorder border
) const 
 458         case wxBORDER_SIMPLE
: 
 459         case wxBORDER_STATIC
: 
 463         case wxBORDER_RAISED
: 
 464         case wxBORDER_SUNKEN
: 
 469         case wxBORDER_DOUBLE
: 
 474             wxFAIL_MSG(wxT("unknown border type")); 
 477         case wxBORDER_DEFAULT
: 
 492 void wxStdRenderer::AdjustSize(wxSize 
*size
, const wxWindow 
*window
) 
 494     // take into account the border width 
 495     wxRect rectBorder 
= GetBorderDimensions(window
->GetBorder()); 
 496     size
->x 
+= rectBorder
.x 
+ rectBorder
.width
; 
 497     size
->y 
+= rectBorder
.y 
+ rectBorder
.height
; 
 500 bool wxStdRenderer::AreScrollbarsInsideBorder() const 
 505 wxCoord 
wxStdRenderer::GetListboxItemHeight(wxCoord fontHeight
) 
 507     return fontHeight 
+ 2*ITEM_MARGIN
; 
 510 void wxStdRenderer::DrawTextBorder(wxDC
& dc
, 
 516     DrawBorder(dc
, border
, rect
, flags
, rectIn
); 
 519 // ---------------------------------------------------------------------------- 
 521 // ---------------------------------------------------------------------------- 
 524 wxStdRenderer::DrawHorizontalLine(wxDC
& dc
, wxCoord y
, wxCoord x1
, wxCoord x2
) 
 526     dc
.SetPen(m_penDarkGrey
); 
 527     dc
.DrawLine(x1
, y
, x2 
+ 1, y
); 
 529     dc
.SetPen(m_penHighlight
); 
 531     dc
.DrawLine(x1
, y
, x2 
+ 1, y
); 
 535 wxStdRenderer::DrawVerticalLine(wxDC
& dc
, wxCoord x
, wxCoord y1
, wxCoord y2
) 
 537     dc
.SetPen(m_penDarkGrey
); 
 538     dc
.DrawLine(x
, y1
, x
, y2 
+ 1); 
 540     dc
.SetPen(m_penHighlight
); 
 542     dc
.DrawLine(x
, y1
, x
, y2 
+ 1); 
 545 void wxStdRenderer::DrawFrameWithoutLabel(wxDC
& dc
, 
 546                                           const wxRect
& rectFrame
, 
 547                                           const wxRect
& rectLabel
) 
 549     // draw left, bottom and right lines entirely 
 550     DrawVerticalLine(dc
, rectFrame
.GetLeft(), 
 551                      rectFrame
.GetTop(), rectFrame
.GetBottom() - 2); 
 552     DrawHorizontalLine(dc
, rectFrame
.GetBottom() - 1, 
 553                        rectFrame
.GetLeft(), rectFrame
.GetRight()); 
 554     DrawVerticalLine(dc
, rectFrame
.GetRight() - 1, 
 555                      rectFrame
.GetTop(), rectFrame
.GetBottom() - 1); 
 557     // and 2 parts of the top line 
 558     DrawHorizontalLine(dc
, rectFrame
.GetTop(), 
 559                        rectFrame
.GetLeft() + 1, rectLabel
.GetLeft()); 
 560     DrawHorizontalLine(dc
, rectFrame
.GetTop(), 
 561                        rectLabel
.GetRight(), rectFrame
.GetRight() - 2); 
 564 void wxStdRenderer::DrawFrameWithLabel(wxDC
& dc
, 
 565                                        const wxString
& label
, 
 566                                        const wxRect
& rectFrame
, 
 567                                        const wxRect
& rectText
, 
 573     DrawLabel(dc
, label
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
); 
 575     DrawFrameWithoutLabel(dc
, rectFrame
, rectLabel
); 
 578 void wxStdRenderer::DrawFrame(wxDC
& dc
, 
 579                               const wxString
& label
, 
 585     wxCoord height 
= 0; // of the label 
 586     wxRect rectFrame 
= rect
; 
 587     if ( !label
.empty() ) 
 589         // the text should touch the top border of the rect, so the frame 
 590         // itself should be lower 
 591         dc
.GetTextExtent(label
, NULL
, &height
); 
 592         rectFrame
.y 
+= height 
/ 2; 
 593         rectFrame
.height 
-= height 
/ 2; 
 595         // we have to draw each part of the frame individually as we can't 
 596         // erase the background beyond the label as it might contain some 
 597         // pixmap already, so drawing everything and then overwriting part of 
 598         // the frame with label doesn't work 
 600         // TODO: the +5 shouldn't be hard coded 
 602         rectText
.x 
= rectFrame
.x 
+ 5; 
 604         rectText
.width 
= rectFrame
.width 
- 7; // +2 border width 
 605         rectText
.height 
= height
; 
 607         DrawFrameWithLabel(dc
, label
, rectFrame
, rectText
, flags
, 
 608                            alignment
, indexAccel
); 
 612         DrawBoxBorder(dc
, &rectFrame
); 
 616 void wxStdRenderer::DrawItem(wxDC
& dc
, 
 617                              const wxString
& label
, 
 621     wxDCTextColourChanger 
colChanger(dc
); 
 623     if ( flags 
& wxCONTROL_SELECTED 
) 
 625         colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
)); 
 627         const wxColour colBg 
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
); 
 630         dc
.DrawRectangle(rect
); 
 633     // horizontal adjustment is arbitrary 
 634     wxRect rectText 
= rect
; 
 635     rectText
.Deflate(2, ITEM_MARGIN
); 
 636     dc
.DrawLabel(label
, wxNullBitmap
, rectText
); 
 638     if ( flags 
& wxCONTROL_FOCUSED 
) 
 640         DrawFocusRect(NULL
, dc
, rect
, flags
); 
 644 void wxStdRenderer::DrawCheckItemBitmap(wxDC
& dc
, 
 645                                         const wxBitmap
& bitmap
, 
 649     DrawCheckButton(dc
, wxEmptyString
, bitmap
, rect
, flags
); 
 652 void wxStdRenderer::DrawCheckItem(wxDC
& dc
, 
 653                                   const wxString
& label
, 
 654                                   const wxBitmap
& bitmap
, 
 658     wxRect rectBitmap 
= rect
; 
 659     rectBitmap
.width 
= GetCheckBitmapSize().x
; 
 660     DrawCheckItemBitmap(dc
, bitmap
, rectBitmap
, flags
); 
 662     wxRect rectLabel 
= rect
; 
 663     wxCoord shift 
= rectBitmap
.width 
+ 2*GetCheckItemMargin(); 
 664     rectLabel
.x 
+= shift
; 
 665     rectLabel
.width 
-= shift
; 
 666     DrawItem(dc
, label
, rectLabel
, flags
); 
 669 // ---------------------------------------------------------------------------- 
 670 // check and radio bitmaps 
 671 // ---------------------------------------------------------------------------- 
 673 void wxStdRenderer::DrawCheckButton(wxDC
& dc
, 
 674                                     const wxString
& label
, 
 675                                     const wxBitmap
& bitmap
, 
 682         DrawCheckOrRadioButton(dc
, label
, bitmap
, rect
, flags
, align
, indexAccel
); 
 684         DrawCheckOrRadioButton(dc
, label
, GetCheckBitmap(flags
), rect
, flags
, align
, indexAccel
); 
 687 void wxStdRenderer::DrawRadioButton(wxDC
& dc
, 
 688                                     const wxString
& label
, 
 689                                     const wxBitmap
& bitmap
, 
 696         DrawCheckOrRadioButton(dc
, label
, bitmap
, rect
, flags
, align
, indexAccel
); 
 698         DrawCheckOrRadioButton(dc
, label
, GetRadioBitmap(flags
), rect
, flags
, align
, indexAccel
); 
 702 void wxStdRenderer::DrawCheckOrRadioButton(wxDC
& dc
, 
 703                                            const wxString
& label
, 
 704                                            const wxBitmap
& bitmap
, 
 710     // calculate the position of the bitmap and of the label 
 711     wxCoord heightBmp 
= bitmap
.GetHeight(); 
 713             yBmp 
= rect
.y 
+ (rect
.height 
- heightBmp
) / 2; 
 716     dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
); 
 717     rectLabel
.y 
= rect
.y 
+ (rect
.height 
- rectLabel
.height
) / 2; 
 719     // align label vertically with the bitmap - looks nicer like this 
 720     rectLabel
.y 
-= (rectLabel
.height 
- heightBmp
) % 2; 
 722     // calc horz position 
 723     if ( align 
== wxALIGN_RIGHT 
) 
 725         xBmp 
= rect
.GetRight() - bitmap
.GetWidth(); 
 726         rectLabel
.x 
= rect
.x 
+ 3; 
 727         rectLabel
.SetRight(xBmp
); 
 729     else // normal (checkbox to the left of the text) case 
 732         rectLabel
.x 
= xBmp 
+ bitmap
.GetWidth() + 5; 
 733         rectLabel
.SetRight(rect
.GetRight()); 
 736     dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, true /* use mask */); 
 738     DrawLabel(dc
, label
, rectLabel
, flags
, 
 739               wxALIGN_LEFT 
| wxALIGN_TOP
, indexAccel
); 
 744 void wxStdRenderer::DrawTextLine(wxDC
& dc
, 
 745                                  const wxString
& text
, 
 751     if ( (selStart 
== -1) || !(flags 
& wxCONTROL_FOCUSED
) ) 
 753         // just draw it as is 
 754         dc
.DrawText(text
, rect
.x
, rect
.y
); 
 756     else // we have selection 
 761         // draw the part before selection 
 762         wxString 
s(text
, (size_t)selStart
); 
 765             dc
.DrawText(s
, x
, rect
.y
); 
 767             dc
.GetTextExtent(s
, &width
, NULL
); 
 771         // draw the selection itself 
 772         s 
= wxString(text
.c_str() + selStart
, text
.c_str() + selEnd
); 
 775             wxColour colFg 
= dc
.GetTextForeground(), 
 776                      colBg 
= dc
.GetTextBackground(); 
 777             dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
)); 
 778             dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
)); 
 779             dc
.SetBackgroundMode(wxSOLID
); 
 781             dc
.DrawText(s
, x
, rect
.y
); 
 782             dc
.GetTextExtent(s
, &width
, NULL
); 
 785             dc
.SetBackgroundMode(wxTRANSPARENT
); 
 786             dc
.SetTextBackground(colBg
); 
 787             dc
.SetTextForeground(colFg
); 
 790         // draw the final part 
 791         s 
= text
.c_str() + selEnd
; 
 794             dc
.DrawText(s
, x
, rect
.y
); 
 799 void wxStdRenderer::DrawLineWrapMark(wxDC
& WXUNUSED(dc
), 
 800                                      const wxRect
& WXUNUSED(rect
)) 
 802     // nothing by default 
 805 int wxStdRenderer::GetTextBorderWidth(const wxTextCtrl 
* WXUNUSED(text
)) const 
 811 wxStdRenderer::GetTextTotalArea(const wxTextCtrl 
*text
, const wxRect
& rect
) const 
 813     wxRect rectTotal 
= rect
; 
 814     rectTotal
.Inflate(GetTextBorderWidth(text
)); 
 818 wxRect 
wxStdRenderer::GetTextClientArea(const wxTextCtrl 
*text
, 
 820                                         wxCoord 
*extraSpaceBeyond
) const 
 822     wxRect rectText 
= rect
; 
 823     rectText
.Deflate(GetTextBorderWidth(text
)); 
 825     if ( extraSpaceBeyond 
) 
 826         *extraSpaceBeyond 
= 0; 
 831 #endif // wxUSE_TEXTCTRL 
 833 // ---------------------------------------------------------------------------- 
 834 // scrollbars drawing 
 835 // ---------------------------------------------------------------------------- 
 837 void wxStdRenderer::DrawScrollbarArrow(wxDC
& dc
, 
 842     DrawArrow(dc
, dir
, rect
, flags
); 
 845 void wxStdRenderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
) 
 847     DrawSolidRect(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
); 
 850 // ---------------------------------------------------------------------------- 
 852 // ---------------------------------------------------------------------------- 
 856 wxSize 
wxStdRenderer::GetStatusBarBorders() const 
 858     // Rendered border may be different depending on field's style, we use 
 859     // the largest value so that any field certainly fits into the borders 
 861     wxRect raised 
= GetBorderDimensions(wxBORDER_RAISED
); 
 862     wxRect flat 
= GetBorderDimensions(wxBORDER_STATIC
); 
 863     wxASSERT_MSG( raised
.x 
== raised
.width 
&& raised
.y 
== raised
.height 
&& 
 864                   flat
.x 
== flat
.width 
&& flat
.y 
== flat
.height
, 
 865                   wxT("this code expects uniform borders, you must override GetStatusBarBorders") ); 
 867     // take the larger of flat/raised values: 
 868     wxSize 
border(wxMax(raised
.x
, flat
.x
), wxMax(raised
.y
, flat
.y
)); 
 873 wxCoord 
wxStdRenderer::GetStatusBarBorderBetweenFields() const 
 878 wxSize 
wxStdRenderer::GetStatusBarFieldMargins() const 
 883 void wxStdRenderer::DrawStatusField(wxDC
& dc
, 
 885                                     const wxString
& label
, 
 891     if ( style 
== wxSB_RAISED 
) 
 892         DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
); 
 893     else if ( style 
!= wxSB_FLAT 
) 
 894         DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
); 
 898     rectIn
.Deflate(GetStatusBarFieldMargins()); 
 900     wxDCClipper 
clipper(dc
, rectIn
); 
 901     DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT 
| wxALIGN_CENTRE_VERTICAL
); 
 904 #endif // wxUSE_STATUSBAR 
 906 // ---------------------------------------------------------------------------- 
 908 // ---------------------------------------------------------------------------- 
 910 int wxStdRenderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const 
 912     wxRect client 
= GetFrameClientArea(rect
, flags
); 
 914     if ( client
.Contains(pt
) ) 
 915         return wxHT_TOPLEVEL_CLIENT_AREA
; 
 917     if ( flags 
& wxTOPLEVEL_TITLEBAR 
) 
 919         wxRect client 
= GetFrameClientArea(rect
, flags 
& ~wxTOPLEVEL_TITLEBAR
); 
 921         if ( flags 
& wxTOPLEVEL_ICON 
) 
 923             if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Contains(pt
) ) 
 924                 return wxHT_TOPLEVEL_ICON
; 
 927         wxRect 
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
, 
 928                        client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2, 
 929                        FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
); 
 931         if ( flags 
& wxTOPLEVEL_BUTTON_CLOSE 
) 
 933             if ( btnRect
.Contains(pt
) ) 
 934                 return wxHT_TOPLEVEL_BUTTON_CLOSE
; 
 935             btnRect
.x 
-= FRAME_BUTTON_WIDTH 
+ 2; 
 937         if ( flags 
& wxTOPLEVEL_BUTTON_MAXIMIZE 
) 
 939             if ( btnRect
.Contains(pt
) ) 
 940                 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
; 
 941             btnRect
.x 
-= FRAME_BUTTON_WIDTH
; 
 943         if ( flags 
& wxTOPLEVEL_BUTTON_RESTORE 
) 
 945             if ( btnRect
.Contains(pt
) ) 
 946                 return wxHT_TOPLEVEL_BUTTON_RESTORE
; 
 947             btnRect
.x 
-= FRAME_BUTTON_WIDTH
; 
 949         if ( flags 
& wxTOPLEVEL_BUTTON_ICONIZE 
) 
 951             if ( btnRect
.Contains(pt
) ) 
 952                 return wxHT_TOPLEVEL_BUTTON_ICONIZE
; 
 953             btnRect
.x 
-= FRAME_BUTTON_WIDTH
; 
 955         if ( flags 
& wxTOPLEVEL_BUTTON_HELP 
) 
 957             if ( btnRect
.Contains(pt
) ) 
 958                 return wxHT_TOPLEVEL_BUTTON_HELP
; 
 959             btnRect
.x 
-= FRAME_BUTTON_WIDTH
; 
 962         if ( pt
.y 
>= client
.y 
&& pt
.y 
< client
.y 
+ FRAME_TITLEBAR_HEIGHT 
) 
 963             return wxHT_TOPLEVEL_TITLEBAR
; 
 966     if ( (flags 
& wxTOPLEVEL_BORDER
) && !(flags 
& wxTOPLEVEL_MAXIMIZED
) ) 
 968         // we are certainly at one of borders, let's decide which one: 
 971         // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined! 
 972         if ( pt
.x 
< client
.x 
) 
 973             border 
|= wxHT_TOPLEVEL_BORDER_W
; 
 974         else if ( pt
.x 
>= client
.width 
+ client
.x 
) 
 975             border 
|= wxHT_TOPLEVEL_BORDER_E
; 
 976         if ( pt
.y 
< client
.y 
) 
 977             border 
|= wxHT_TOPLEVEL_BORDER_N
; 
 978         else if ( pt
.y 
>= client
.height 
+ client
.y 
) 
 979             border 
|= wxHT_TOPLEVEL_BORDER_S
; 
 986 void wxStdRenderer::DrawFrameTitleBar(wxDC
& dc
, 
 988                                       const wxString
& title
, 
 992                                       int specialButtonFlags
) 
 994     if ( (flags 
& wxTOPLEVEL_BORDER
) && !(flags 
& wxTOPLEVEL_MAXIMIZED
) ) 
 996         DrawFrameBorder(dc
, rect
, flags
); 
 998     if ( flags 
& wxTOPLEVEL_TITLEBAR 
) 
1000         DrawFrameBackground(dc
, rect
, flags
); 
1001         if ( flags 
& wxTOPLEVEL_ICON 
) 
1002             DrawFrameIcon(dc
, rect
, icon
, flags
); 
1003         DrawFrameTitle(dc
, rect
, title
, flags
); 
1005         wxRect client 
= GetFrameClientArea(rect
, flags 
& ~wxTOPLEVEL_TITLEBAR
); 
1007         x 
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
; 
1008         y 
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2; 
1010         if ( flags 
& wxTOPLEVEL_BUTTON_CLOSE 
) 
1012             DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
, 
1013                             (specialButton 
== wxTOPLEVEL_BUTTON_CLOSE
) ? 
1014                             specialButtonFlags 
: 0); 
1015             x 
-= FRAME_BUTTON_WIDTH 
+ 2; 
1017         if ( flags 
& wxTOPLEVEL_BUTTON_MAXIMIZE 
) 
1019             DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
, 
1020                             (specialButton 
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ? 
1021                             specialButtonFlags 
: 0); 
1022             x 
-= FRAME_BUTTON_WIDTH
; 
1024         if ( flags 
& wxTOPLEVEL_BUTTON_RESTORE 
) 
1026             DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
, 
1027                             (specialButton 
== wxTOPLEVEL_BUTTON_RESTORE
) ? 
1028                             specialButtonFlags 
: 0); 
1029             x 
-= FRAME_BUTTON_WIDTH
; 
1031         if ( flags 
& wxTOPLEVEL_BUTTON_ICONIZE 
) 
1033             DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
, 
1034                             (specialButton 
== wxTOPLEVEL_BUTTON_ICONIZE
) ? 
1035                             specialButtonFlags 
: 0); 
1036             x 
-= FRAME_BUTTON_WIDTH
; 
1038         if ( flags 
& wxTOPLEVEL_BUTTON_HELP 
) 
1040             DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
, 
1041                             (specialButton 
== wxTOPLEVEL_BUTTON_HELP
) ? 
1042                             specialButtonFlags 
: 0); 
1047 void wxStdRenderer::DrawFrameBorder(wxDC
& dc
, const wxRect
& rect
, int flags
) 
1049     if ( !(flags 
& wxTOPLEVEL_BORDER
) ) 
1054     DrawAntiSunkenBorder(dc
, &r
); 
1055     DrawExtraBorder(dc
, &r
); 
1056     if ( flags 
& wxTOPLEVEL_RESIZEABLE 
) 
1057         DrawExtraBorder(dc
, &r
); 
1060 void wxStdRenderer::DrawFrameBackground(wxDC
& dc
, const wxRect
& rect
, int flags
) 
1062     if ( !(flags 
& wxTOPLEVEL_TITLEBAR
) ) 
1065     wxColour col 
= m_scheme
->Get(flags 
& wxTOPLEVEL_ACTIVE
 
1066                                     ? wxColourScheme::TITLEBAR_ACTIVE
 
1067                                     : wxColourScheme::TITLEBAR
); 
1069     wxRect r 
= GetFrameClientArea(rect
, flags 
& ~wxTOPLEVEL_TITLEBAR
); 
1070     r
.height 
= FRAME_TITLEBAR_HEIGHT
; 
1072     DrawBackground(dc
, col
, r
); 
1075 void wxStdRenderer::DrawFrameTitle(wxDC
& dc
, 
1077                                    const wxString
& title
, 
1080     wxColour col 
= m_scheme
->Get(flags 
& wxTOPLEVEL_ACTIVE
 
1081                                     ? wxColourScheme::TITLEBAR_ACTIVE_TEXT
 
1082                                     : wxColourScheme::TITLEBAR_TEXT
); 
1083     dc
.SetTextForeground(col
); 
1085     wxRect r 
= GetFrameClientArea(rect
, flags 
& ~wxTOPLEVEL_TITLEBAR
); 
1086     r
.height 
= FRAME_TITLEBAR_HEIGHT
; 
1087     if ( flags 
& wxTOPLEVEL_ICON 
) 
1089         r
.x 
+= FRAME_TITLEBAR_HEIGHT
; 
1090         r
.width 
-= FRAME_TITLEBAR_HEIGHT 
+ 2; 
1098     if ( flags 
& wxTOPLEVEL_BUTTON_CLOSE 
) 
1099         r
.width 
-= FRAME_BUTTON_WIDTH 
+ 2; 
1100     if ( flags 
& wxTOPLEVEL_BUTTON_MAXIMIZE 
) 
1101         r
.width 
-= FRAME_BUTTON_WIDTH
; 
1102     if ( flags 
& wxTOPLEVEL_BUTTON_RESTORE 
) 
1103         r
.width 
-= FRAME_BUTTON_WIDTH
; 
1104     if ( flags 
& wxTOPLEVEL_BUTTON_ICONIZE 
) 
1105         r
.width 
-= FRAME_BUTTON_WIDTH
; 
1106     if ( flags 
& wxTOPLEVEL_BUTTON_HELP 
) 
1107         r
.width 
-= FRAME_BUTTON_WIDTH
; 
1109     dc
.SetFont(m_titlebarFont
); 
1113     dc
.GetTextExtent(title
, &textW
, NULL
); 
1114     if ( textW 
> r
.width 
) 
1116         // text is too big, let's shorten it and add "..." after it: 
1117         size_t len 
= title
.length(); 
1118         wxCoord WSoFar
, letterW
; 
1120         dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
); 
1121         if ( WSoFar 
> r
.width 
) 
1123             // not enough space to draw anything 
1128         for (size_t i 
= 0; i 
< len
; i
++) 
1130             dc
.GetTextExtent(title
[i
], &letterW
, NULL
); 
1131             if ( letterW 
+ WSoFar 
> r
.width 
) 
1138     else // no need to truncate the title 
1143     dc
.DrawLabel(s
, wxNullBitmap
, r
, wxALIGN_LEFT 
| wxALIGN_CENTRE_VERTICAL
); 
1146 void wxStdRenderer::DrawFrameIcon(wxDC
& dc
, 
1153         wxRect r 
= GetFrameClientArea(rect
, flags 
& ~wxTOPLEVEL_TITLEBAR
); 
1154         dc
.DrawIcon(icon
, r
.x
, r
.y
); 
1158 void wxStdRenderer::DrawFrameButton(wxDC
& dc
, 
1159                                     wxCoord x
, wxCoord y
, 
1163     FrameButtonType idx
; 
1166         case wxTOPLEVEL_BUTTON_CLOSE
:    idx 
= FrameButton_Close
; break; 
1167         case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx 
= FrameButton_Maximize
; break; 
1168         case wxTOPLEVEL_BUTTON_ICONIZE
:  idx 
= FrameButton_Minimize
; break; 
1169         case wxTOPLEVEL_BUTTON_RESTORE
:  idx 
= FrameButton_Restore
; break; 
1170         case wxTOPLEVEL_BUTTON_HELP
:     idx 
= FrameButton_Help
; break; 
1172             wxFAIL_MSG(wxT("incorrect button specification")); 
1176     wxBitmap bmp 
= GetFrameButtonBitmap(idx
); 
1180     wxRect 
rectBtn(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
); 
1181     if ( flags 
& wxCONTROL_PRESSED 
) 
1183         DrawSunkenBorder(dc
, &rectBtn
); 
1185         rectBtn
.Offset(1, 1); 
1189         DrawRaisedBorder(dc
, &rectBtn
); 
1192     DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rectBtn
); 
1194     wxRect 
rectBmp(0, 0, bmp
.GetWidth(), bmp
.GetHeight()); 
1195     dc
.DrawBitmap(bmp
, rectBmp
.CentreIn(rectBtn
).GetPosition(), true); 
1198 int wxStdRenderer::GetFrameBorderWidth(int flags
) const 
1200     return flags 
& wxTOPLEVEL_RESIZEABLE 
? 4 : 3; 
1204 wxRect 
wxStdRenderer::GetFrameClientArea(const wxRect
& rect
, int flags
) const 
1208     if ( (flags 
& wxTOPLEVEL_BORDER
) && !(flags 
& wxTOPLEVEL_MAXIMIZED
) ) 
1210         r
.Inflate(-GetFrameBorderWidth(flags
)); 
1213     if ( flags 
& wxTOPLEVEL_TITLEBAR 
) 
1215         r
.y 
+= FRAME_TITLEBAR_HEIGHT
; 
1216         r
.height 
-= FRAME_TITLEBAR_HEIGHT
; 
1223 wxStdRenderer::GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const 
1225     wxSize 
s(clientSize
); 
1227     if ( (flags 
& wxTOPLEVEL_BORDER
) && !(flags 
& wxTOPLEVEL_MAXIMIZED
) ) 
1229         s
.IncBy(2*GetFrameBorderWidth(flags
)); 
1232     if ( flags 
& wxTOPLEVEL_TITLEBAR 
) 
1233         s
.y 
+= FRAME_TITLEBAR_HEIGHT
; 
1238 wxSize 
wxStdRenderer::GetFrameMinSize(int flags
) const 
1242     if ( (flags 
& wxTOPLEVEL_BORDER
) && !(flags 
& wxTOPLEVEL_MAXIMIZED
) ) 
1244         s
.IncBy(2*GetFrameBorderWidth(flags
)); 
1247     if ( flags 
& wxTOPLEVEL_TITLEBAR 
) 
1249         s
.y 
+= FRAME_TITLEBAR_HEIGHT
; 
1251         if ( flags 
& wxTOPLEVEL_ICON 
) 
1252             s
.x 
+= FRAME_TITLEBAR_HEIGHT 
+ 2; 
1253         if ( flags 
& wxTOPLEVEL_BUTTON_CLOSE 
) 
1254             s
.x 
+= FRAME_BUTTON_WIDTH 
+ 2; 
1255         if ( flags 
& wxTOPLEVEL_BUTTON_MAXIMIZE 
) 
1256             s
.x 
+= FRAME_BUTTON_WIDTH
; 
1257         if ( flags 
& wxTOPLEVEL_BUTTON_RESTORE 
) 
1258             s
.x 
+= FRAME_BUTTON_WIDTH
; 
1259         if ( flags 
& wxTOPLEVEL_BUTTON_ICONIZE 
) 
1260             s
.x 
+= FRAME_BUTTON_WIDTH
; 
1261         if ( flags 
& wxTOPLEVEL_BUTTON_HELP 
) 
1262             s
.x 
+= FRAME_BUTTON_WIDTH
; 
1268 wxSize 
wxStdRenderer::GetFrameIconSize() const 
1270     return wxSize(16, 16);