1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        src/univ/stdrend.cpp
3 // Purpose:     implementation of wxStdRenderer
4 // Author:      Vadim Zeitlin
5 // Created:     2006-09-16
6 // Copyright:   (c) 2006 Vadim Zeitlin <vadim@wxwidgets.org>
7 // Licence:     wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
9 
10 // ============================================================================
11 // declarations
12 // ============================================================================
13 
14 // ----------------------------------------------------------------------------
15 // headers
16 // ----------------------------------------------------------------------------
17 
18 // for compilers that support precompilation, includes "wx.h".
19 #include "wx/wxprec.h"
20 
21 
22 #ifndef WX_PRECOMP
23     #include "wx/settings.h"
24     #include "wx/brush.h"
25     #include "wx/dc.h"
26     #include "wx/statusbr.h"
27     #include "wx/toplevel.h"
28 #endif //WX_PRECOMP
29 
30 #include "wx/univ/stdrend.h"
31 #include "wx/univ/colschem.h"
32 
33 // ----------------------------------------------------------------------------
34 // constants
35 // ----------------------------------------------------------------------------
36 
37 static const int FRAME_TITLEBAR_HEIGHT             = 18;
38 static const int FRAME_BUTTON_WIDTH                = 16;
39 static const int FRAME_BUTTON_HEIGHT               = 14;
40 
41 // the margin between listbox item text and its rectangle
42 static const int ITEM_MARGIN = 1;
43 
44 // ============================================================================
45 // wxStdRenderer implementation
46 // ============================================================================
47 
48 // ----------------------------------------------------------------------------
49 // ctor
50 // ----------------------------------------------------------------------------
51 
wxStdRenderer(const wxColourScheme * scheme)52 wxStdRenderer::wxStdRenderer(const wxColourScheme *scheme)
53              : m_scheme(scheme)
54 {
55     m_penBlack = wxPen(wxSCHEME_COLOUR(scheme, SHADOW_DARK));
56     m_penDarkGrey = wxPen(wxSCHEME_COLOUR(scheme, SHADOW_OUT));
57     m_penLightGrey = wxPen(wxSCHEME_COLOUR(scheme, SHADOW_IN));
58     m_penHighlight = wxPen(wxSCHEME_COLOUR(scheme, SHADOW_HIGHLIGHT));
59 
60     m_titlebarFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
61     m_titlebarFont.SetWeight(wxFONTWEIGHT_BOLD);
62 }
63 
64 // ----------------------------------------------------------------------------
65 // helper functions
66 // ----------------------------------------------------------------------------
67 
68 void
DrawSolidRect(wxDC & dc,const wxColour & col,const wxRect & rect)69 wxStdRenderer::DrawSolidRect(wxDC& dc, const wxColour& col, const wxRect& rect)
70 {
71     dc.SetBrush(col);
72     dc.SetPen(*wxTRANSPARENT_PEN);
73     dc.DrawRectangle(rect);
74 }
75 
DrawRect(wxDC & dc,wxRect * rect,const wxPen & pen)76 void wxStdRenderer::DrawRect(wxDC& dc, wxRect *rect, const wxPen& pen)
77 {
78     // draw
79     dc.SetPen(pen);
80     dc.SetBrush(*wxTRANSPARENT_BRUSH);
81     dc.DrawRectangle(*rect);
82 
83     // adjust the rect
84     rect->Inflate(-1);
85 }
86 
DrawShadedRect(wxDC & dc,wxRect * rect,const wxPen & pen1,const wxPen & pen2)87 void wxStdRenderer::DrawShadedRect(wxDC& dc, wxRect *rect,
88                                    const wxPen& pen1, const wxPen& pen2)
89 {
90     // draw the rectangle
91     dc.SetPen(pen1);
92     dc.DrawLine(rect->GetLeft(), rect->GetTop(),
93                 rect->GetLeft(), rect->GetBottom());
94     dc.DrawLine(rect->GetLeft() + 1, rect->GetTop(),
95                 rect->GetRight(), rect->GetTop());
96     dc.SetPen(pen2);
97     dc.DrawLine(rect->GetRight(), rect->GetTop(),
98                 rect->GetRight(), rect->GetBottom());
99     dc.DrawLine(rect->GetLeft(), rect->GetBottom(),
100                 rect->GetRight() + 1, rect->GetBottom());
101 
102     // adjust the rect
103     rect->Inflate(-1);
104 }
105 
106 // ----------------------------------------------------------------------------
107 // translate various flags into corresponding renderer constants
108 // ----------------------------------------------------------------------------
109 
110 /* static */
GetIndicatorsFromFlags(int flags,IndicatorState & state,IndicatorStatus & status)111 void wxStdRenderer::GetIndicatorsFromFlags(int flags,
112                                            IndicatorState& state,
113                                            IndicatorStatus& status)
114 {
115     if ( flags & wxCONTROL_SELECTED )
116         state = flags & wxCONTROL_DISABLED ? IndicatorState_SelectedDisabled
117                                            : IndicatorState_Selected;
118     else if ( flags & wxCONTROL_DISABLED )
119         state = IndicatorState_Disabled;
120     else if ( flags & wxCONTROL_PRESSED )
121         state = IndicatorState_Pressed;
122     else
123         state = IndicatorState_Normal;
124 
125     status = flags & wxCONTROL_CHECKED ? IndicatorStatus_Checked
126                                        : flags & wxCONTROL_UNDETERMINED
127                                             ? IndicatorStatus_Undetermined
128                                             : IndicatorStatus_Unchecked;
129 }
130 
131 /* static */
GetArrowDirection(wxDirection dir)132 wxStdRenderer::ArrowDirection wxStdRenderer::GetArrowDirection(wxDirection dir)
133 {
134     switch ( dir )
135     {
136         case wxLEFT:
137             return Arrow_Left;
138 
139         case wxRIGHT:
140             return Arrow_Right;
141 
142         case wxUP:
143             return Arrow_Up;
144 
145         case wxDOWN:
146             return Arrow_Down;
147 
148         default:
149             wxFAIL_MSG(wxT("unknown arrow direction"));
150     }
151 
152     return Arrow_Max;
153 }
154 
155 // ----------------------------------------------------------------------------
156 // background
157 // ----------------------------------------------------------------------------
158 
DrawBackground(wxDC & dc,const wxColour & col,const wxRect & rect,int WXUNUSED (flags),wxWindow * window)159 void wxStdRenderer::DrawBackground(wxDC& dc,
160                                    const wxColour& col,
161                                    const wxRect& rect,
162                                    int WXUNUSED(flags),
163                                    wxWindow *window)
164 {
165     wxColour colBg;
166 
167     if (col.IsOk())
168     {
169         colBg = col;
170     }
171     else if (window)
172     {
173         colBg = m_scheme->GetBackground(window);
174     }
175     else
176     {
177         colBg = wxSCHEME_COLOUR(m_scheme, CONTROL);
178     }
179 
180     DrawSolidRect(dc, colBg, rect);
181 }
182 
183 
DrawButtonSurface(wxDC & dc,const wxColour & col,const wxRect & rect,int flags)184 void wxStdRenderer::DrawButtonSurface(wxDC& dc,
185                                       const wxColour& col,
186                                       const wxRect& rect,
187                                       int flags)
188 {
189     DrawBackground(dc, col, rect, flags);
190 }
191 
192 // ----------------------------------------------------------------------------
193 // text
194 // ----------------------------------------------------------------------------
195 
196 void
DrawFocusRect(wxWindow * WXUNUSED (win),wxDC & dc,const wxRect & rect,int WXUNUSED (flags))197 wxStdRenderer::DrawFocusRect(wxWindow* WXUNUSED(win), wxDC& dc, const wxRect& rect, int WXUNUSED(flags))
198 {
199     // draw the pixels manually because the "dots" in wxPen with wxPENSTYLE_DOT style
200     // may be short traits and not really dots
201     //
202     // note that to behave in the same manner as DrawRect(), we must exclude
203     // the bottom and right borders from the rectangle
204     wxCoord x1 = rect.GetLeft(),
205             y1 = rect.GetTop(),
206             x2 = rect.GetRight(),
207             y2 = rect.GetBottom();
208 
209     dc.SetPen(m_penBlack);
210 
211     // this seems to be closer than what Windows does than wxINVERT although
212     // I'm still not sure if it's correct
213     dc.SetLogicalFunction(wxAND_REVERSE);
214 
215     wxCoord z;
216     for ( z = x1 + 1; z < x2; z += 2 )
217         dc.DrawPoint(z, rect.GetTop());
218 
219     wxCoord shift = z == x2 ? 0 : 1;
220     for ( z = y1 + shift; z < y2; z += 2 )
221         dc.DrawPoint(x2, z);
222 
223     shift = z == y2 ? 0 : 1;
224     for ( z = x2 - shift; z > x1; z -= 2 )
225         dc.DrawPoint(z, y2);
226 
227     shift = z == x1 ? 0 : 1;
228     for ( z = y2 - shift; z > y1; z -= 2 )
229         dc.DrawPoint(x1, z);
230 
231     dc.SetLogicalFunction(wxCOPY);
232 }
233 
DrawLabel(wxDC & dc,const wxString & label,const wxRect & rect,int flags,int alignment,int indexAccel,wxRect * rectBounds)234 void wxStdRenderer::DrawLabel(wxDC& dc,
235                               const wxString& label,
236                               const wxRect& rect,
237                               int flags,
238                               int alignment,
239                               int indexAccel,
240                               wxRect *rectBounds)
241 {
242     DrawButtonLabel(dc, label, wxNullBitmap, rect, flags,
243                     alignment, indexAccel, rectBounds);
244 }
245 
DrawButtonLabel(wxDC & dc,const wxString & label,const wxBitmap & image,const wxRect & rect,int flags,int alignment,int indexAccel,wxRect * rectBounds)246 void wxStdRenderer::DrawButtonLabel(wxDC& dc,
247                                     const wxString& label,
248                                     const wxBitmap& image,
249                                     const wxRect& rect,
250                                     int flags,
251                                     int alignment,
252                                     int indexAccel,
253                                     wxRect *rectBounds)
254 {
255     wxDCTextColourChanger clrChanger(dc);
256 
257     wxRect rectLabel = rect;
258     if ( !label.empty() && (flags & wxCONTROL_DISABLED) )
259     {
260         if ( flags & wxCONTROL_PRESSED )
261         {
262             // shift the label if a button is pressed
263             rectLabel.Offset(1, 1);
264         }
265 
266         // draw shadow of the text
267         clrChanger.Set(m_penHighlight.GetColour());
268         wxRect rectShadow = rect;
269         rectShadow.Offset(1, 1);
270         dc.DrawLabel(label, rectShadow, alignment, indexAccel);
271 
272         // make the main label text grey
273         clrChanger.Set(m_penDarkGrey.GetColour());
274 
275         if ( flags & wxCONTROL_FOCUSED )
276         {
277             // leave enough space for the focus rect
278             rectLabel.Inflate(-2);
279         }
280     }
281 
282     dc.DrawLabel(label, image, rectLabel, alignment, indexAccel, rectBounds);
283 
284     if ( !label.empty() && (flags & wxCONTROL_FOCUSED) )
285     {
286         rectLabel.Inflate(-1);
287 
288         DrawFocusRect(NULL, dc, rectLabel);
289     }
290 }
291 
292 // ----------------------------------------------------------------------------
293 // borders
294 // ----------------------------------------------------------------------------
295 
296 /*
297    We implement standard-looking 3D borders which have the following appearance:
298 
299    The raised border:
300 
301    WWWWWWWWWWWWWWWWWWWWWWB
302    WHHHHHHHHHHHHHHHHHHHHGB
303    WH                   GB  W = white       (HILIGHT)
304    WH                   GB  H = light grey  (LIGHT)
305    WH                   GB  G = dark grey   (SHADOI)
306    WH                   GB  B = black       (DKSHADOI)
307    WH                   GB
308    WH                   GB
309    WGGGGGGGGGGGGGGGGGGGGGB
310    BBBBBBBBBBBBBBBBBBBBBBB
311 
312    The sunken border looks like this:
313 
314    GGGGGGGGGGGGGGGGGGGGGGW
315    GBBBBBBBBBBBBBBBBBBBBHW
316    GB                   HW
317    GB                   HW
318    GB                   HW
319    GB                   HW
320    GB                   HW
321    GB                   HW
322    GHHHHHHHHHHHHHHHHHHHHHW
323    WWWWWWWWWWWWWWWWWWWWWWW
324 
325    The static border (used for the controls which don't get focus) is like
326    this:
327 
328    GGGGGGGGGGGGGGGGGGGGGGW
329    G                     W
330    G                     W
331    G                     W
332    G                     W
333    G                     W
334    G                     W
335    G                     W
336    WWWWWWWWWWWWWWWWWWWWWWW
337 
338    The most complicated is the double border which is a combination of special
339    "anti-sunken" border and an extra border inside it:
340 
341    HHHHHHHHHHHHHHHHHHHHHHB
342    HWWWWWWWWWWWWWWWWWWWWGB
343    HWHHHHHHHHHHHHHHHHHHHGB
344    HWH                 HGB
345    HWH                 HGB
346    HWH                 HGB
347    HWH                 HGB
348    HWHHHHHHHHHHHHHHHHHHHGB
349    HGGGGGGGGGGGGGGGGGGGGGB
350    BBBBBBBBBBBBBBBBBBBBBBB
351 
352    And the simple border is, well, simple:
353 
354    BBBBBBBBBBBBBBBBBBBBBBB
355    B                     B
356    B                     B
357    B                     B
358    B                     B
359    B                     B
360    B                     B
361    B                     B
362    B                     B
363    BBBBBBBBBBBBBBBBBBBBBBB
364 */
365 
DrawRaisedBorder(wxDC & dc,wxRect * rect)366 void wxStdRenderer::DrawRaisedBorder(wxDC& dc, wxRect *rect)
367 {
368     DrawShadedRect(dc, rect, m_penHighlight, m_penBlack);
369     DrawShadedRect(dc, rect, m_penLightGrey, m_penDarkGrey);
370 }
371 
DrawSunkenBorder(wxDC & dc,wxRect * rect)372 void wxStdRenderer::DrawSunkenBorder(wxDC& dc, wxRect *rect)
373 {
374     DrawShadedRect(dc, rect, m_penDarkGrey, m_penHighlight);
375     DrawShadedRect(dc, rect, m_penBlack, m_penLightGrey);
376 }
377 
DrawAntiSunkenBorder(wxDC & dc,wxRect * rect)378 void wxStdRenderer::DrawAntiSunkenBorder(wxDC& dc, wxRect *rect)
379 {
380     DrawShadedRect(dc, rect, m_penLightGrey, m_penBlack);
381     DrawShadedRect(dc, rect, m_penHighlight, m_penDarkGrey);
382 }
383 
DrawBoxBorder(wxDC & dc,wxRect * rect)384 void wxStdRenderer::DrawBoxBorder(wxDC& dc, wxRect *rect)
385 {
386     DrawShadedRect(dc, rect, m_penDarkGrey, m_penHighlight);
387     DrawShadedRect(dc, rect, m_penHighlight, m_penDarkGrey);
388 }
389 
DrawStaticBorder(wxDC & dc,wxRect * rect)390 void wxStdRenderer::DrawStaticBorder(wxDC& dc, wxRect *rect)
391 {
392     DrawShadedRect(dc, rect, m_penDarkGrey, m_penHighlight);
393 }
394 
DrawExtraBorder(wxDC & dc,wxRect * rect)395 void wxStdRenderer::DrawExtraBorder(wxDC& dc, wxRect *rect)
396 {
397     DrawRect(dc, rect, m_penLightGrey);
398 }
399 
DrawBorder(wxDC & dc,wxBorder border,const wxRect & rectTotal,int WXUNUSED (flags),wxRect * rectIn)400 void wxStdRenderer::DrawBorder(wxDC& dc,
401                                wxBorder border,
402                                const wxRect& rectTotal,
403                                int WXUNUSED(flags),
404                                wxRect *rectIn)
405 {
406     wxRect rect = rectTotal;
407 
408     switch ( border )
409     {
410         case wxBORDER_SUNKEN:
411         case wxBORDER_THEME:
412             DrawSunkenBorder(dc, &rect);
413             break;
414 
415         // wxBORDER_DOUBLE and wxBORDER_THEME are currently the same value.
416 #if 0
417         case wxBORDER_DOUBLE:
418             DrawAntiSunkenBorder(dc, &rect);
419             DrawExtraBorder(dc, &rect);
420             break;
421 #endif
422 
423         case wxBORDER_STATIC:
424             DrawStaticBorder(dc, &rect);
425             break;
426 
427         case wxBORDER_RAISED:
428             DrawRaisedBorder(dc, &rect);
429             break;
430 
431         case wxBORDER_SIMPLE:
432             DrawRect(dc, &rect, m_penBlack);
433             break;
434 
435         default:
436             wxFAIL_MSG(wxT("unknown border type"));
437             // fall through
438 
439         case wxBORDER_DEFAULT:
440         case wxBORDER_NONE:
441             break;
442     }
443 
444     if ( rectIn )
445         *rectIn = rect;
446 }
447 
GetBorderDimensions(wxBorder border) const448 wxRect wxStdRenderer::GetBorderDimensions(wxBorder border) const
449 {
450     wxCoord width;
451     switch ( border )
452     {
453         case wxBORDER_SIMPLE:
454         case wxBORDER_STATIC:
455             width = 1;
456             break;
457 
458         case wxBORDER_RAISED:
459         case wxBORDER_SUNKEN:
460         case wxBORDER_THEME:
461             width = 2;
462             break;
463 #if 0
464         case wxBORDER_DOUBLE:
465             width = 3;
466             break;
467 #endif
468         default:
469             wxFAIL_MSG(wxT("unknown border type"));
470             // fall through
471 
472         case wxBORDER_DEFAULT:
473         case wxBORDER_NONE:
474             width = 0;
475             break;
476     }
477 
478     wxRect rect;
479     rect.x =
480     rect.y =
481     rect.width =
482     rect.height = width;
483 
484     return rect;
485 }
486 
AdjustSize(wxSize * size,const wxWindow * window)487 void wxStdRenderer::AdjustSize(wxSize *size, const wxWindow *window)
488 {
489     // take into account the border width
490     wxRect rectBorder = GetBorderDimensions(window->GetBorder());
491     size->x += rectBorder.x + rectBorder.width;
492     size->y += rectBorder.y + rectBorder.height;
493 }
494 
AreScrollbarsInsideBorder() const495 bool wxStdRenderer::AreScrollbarsInsideBorder() const
496 {
497     return false;
498 }
499 
GetListboxItemHeight(wxCoord fontHeight)500 wxCoord wxStdRenderer::GetListboxItemHeight(wxCoord fontHeight)
501 {
502     return fontHeight + 2*ITEM_MARGIN;
503 }
504 
DrawTextBorder(wxDC & dc,wxBorder border,const wxRect & rect,int flags,wxRect * rectIn)505 void wxStdRenderer::DrawTextBorder(wxDC& dc,
506                                    wxBorder border,
507                                    const wxRect& rect,
508                                    int flags,
509                                    wxRect *rectIn)
510 {
511     DrawBorder(dc, border, rect, flags, rectIn);
512 }
513 
514 // ----------------------------------------------------------------------------
515 // lines and boxes
516 // ----------------------------------------------------------------------------
517 
518 void
DrawHorizontalLine(wxDC & dc,wxCoord y,wxCoord x1,wxCoord x2)519 wxStdRenderer::DrawHorizontalLine(wxDC& dc, wxCoord y, wxCoord x1, wxCoord x2)
520 {
521     dc.SetPen(m_penDarkGrey);
522     dc.DrawLine(x1, y, x2 + 1, y);
523 
524     dc.SetPen(m_penHighlight);
525     y++;
526     dc.DrawLine(x1, y, x2 + 1, y);
527 }
528 
529 void
DrawVerticalLine(wxDC & dc,wxCoord x,wxCoord y1,wxCoord y2)530 wxStdRenderer::DrawVerticalLine(wxDC& dc, wxCoord x, wxCoord y1, wxCoord y2)
531 {
532     dc.SetPen(m_penDarkGrey);
533     dc.DrawLine(x, y1, x, y2 + 1);
534 
535     dc.SetPen(m_penHighlight);
536     x++;
537     dc.DrawLine(x, y1, x, y2 + 1);
538 }
539 
DrawFrameWithoutLabel(wxDC & dc,const wxRect & rectFrame,const wxRect & rectLabel)540 void wxStdRenderer::DrawFrameWithoutLabel(wxDC& dc,
541                                           const wxRect& rectFrame,
542                                           const wxRect& rectLabel)
543 {
544     // draw left, bottom and right lines entirely
545     DrawVerticalLine(dc, rectFrame.GetLeft(),
546                      rectFrame.GetTop(), rectFrame.GetBottom() - 2);
547     DrawHorizontalLine(dc, rectFrame.GetBottom() - 1,
548                        rectFrame.GetLeft(), rectFrame.GetRight());
549     DrawVerticalLine(dc, rectFrame.GetRight() - 1,
550                      rectFrame.GetTop(), rectFrame.GetBottom() - 1);
551 
552     // and 2 parts of the top line
553     DrawHorizontalLine(dc, rectFrame.GetTop(),
554                        rectFrame.GetLeft() + 1, rectLabel.GetLeft());
555     DrawHorizontalLine(dc, rectFrame.GetTop(),
556                        rectLabel.GetRight(), rectFrame.GetRight() - 2);
557 }
558 
DrawFrameWithLabel(wxDC & dc,const wxString & label,const wxRect & rectFrame,const wxRect & rectText,int flags,int alignment,int indexAccel)559 void wxStdRenderer::DrawFrameWithLabel(wxDC& dc,
560                                        const wxString& label,
561                                        const wxRect& rectFrame,
562                                        const wxRect& rectText,
563                                        int flags,
564                                        int alignment,
565                                        int indexAccel)
566 {
567     wxRect rectLabel;
568     DrawLabel(dc, label, rectText, flags, alignment, indexAccel, &rectLabel);
569 
570     DrawFrameWithoutLabel(dc, rectFrame, rectLabel);
571 }
572 
DrawFrame(wxDC & dc,const wxString & label,const wxRect & rect,int flags,int alignment,int indexAccel)573 void wxStdRenderer::DrawFrame(wxDC& dc,
574                               const wxString& label,
575                               const wxRect& rect,
576                               int flags,
577                               int alignment,
578                               int indexAccel)
579 {
580     wxCoord height = 0; // of the label
581     wxRect rectFrame = rect;
582     if ( !label.empty() )
583     {
584         // the text should touch the top border of the rect, so the frame
585         // itself should be lower
586         dc.GetTextExtent(label, NULL, &height);
587         rectFrame.y += height / 2;
588         rectFrame.height -= height / 2;
589 
590         // we have to draw each part of the frame individually as we can't
591         // erase the background beyond the label as it might contain some
592         // pixmap already, so drawing everything and then overwriting part of
593         // the frame with label doesn't work
594 
595         // TODO: the +5 shouldn't be hard coded
596         wxRect rectText;
597         rectText.x = rectFrame.x + 5;
598         rectText.y = rect.y;
599         rectText.width = rectFrame.width - 7; // +2 border width
600         rectText.height = height;
601 
602         DrawFrameWithLabel(dc, label, rectFrame, rectText, flags,
603                            alignment, indexAccel);
604     }
605     else // no label
606     {
607         DrawBoxBorder(dc, &rectFrame);
608     }
609 }
610 
DrawItem(wxDC & dc,const wxString & label,const wxRect & rect,int flags)611 void wxStdRenderer::DrawItem(wxDC& dc,
612                              const wxString& label,
613                              const wxRect& rect,
614                              int flags)
615 {
616     wxDCTextColourChanger colChanger(dc);
617 
618     if ( flags & wxCONTROL_SELECTED )
619     {
620         colChanger.Set(wxSCHEME_COLOUR(m_scheme, HIGHLIGHT_TEXT));
621 
622         const wxColour colBg = wxSCHEME_COLOUR(m_scheme, HIGHLIGHT);
623         dc.SetBrush(colBg);
624         dc.SetPen(colBg);
625         dc.DrawRectangle(rect);
626     }
627 
628     // horizontal adjustment is arbitrary
629     wxRect rectText = rect;
630     rectText.Deflate(2, ITEM_MARGIN);
631     dc.DrawLabel(label, wxNullBitmap, rectText);
632 
633     if ( flags & wxCONTROL_FOCUSED )
634     {
635         DrawFocusRect(NULL, dc, rect, flags);
636     }
637 }
638 
DrawCheckItemBitmap(wxDC & dc,const wxBitmap & bitmap,const wxRect & rect,int flags)639 void wxStdRenderer::DrawCheckItemBitmap(wxDC& dc,
640                                         const wxBitmap& bitmap,
641                                         const wxRect& rect,
642                                         int flags)
643 {
644     DrawCheckButton(dc, wxEmptyString, bitmap, rect, flags);
645 }
646 
DrawCheckItem(wxDC & dc,const wxString & label,const wxBitmap & bitmap,const wxRect & rect,int flags)647 void wxStdRenderer::DrawCheckItem(wxDC& dc,
648                                   const wxString& label,
649                                   const wxBitmap& bitmap,
650                                   const wxRect& rect,
651                                   int flags)
652 {
653     wxRect rectBitmap = rect;
654     rectBitmap.width = GetCheckBitmapSize().x;
655     DrawCheckItemBitmap(dc, bitmap, rectBitmap, flags);
656 
657     wxRect rectLabel = rect;
658     wxCoord shift = rectBitmap.width + 2*GetCheckItemMargin();
659     rectLabel.x += shift;
660     rectLabel.width -= shift;
661     DrawItem(dc, label, rectLabel, flags);
662 }
663 
664 // ----------------------------------------------------------------------------
665 // check and radio bitmaps
666 // ----------------------------------------------------------------------------
667 
DrawCheckButton(wxDC & dc,const wxString & label,const wxBitmap & bitmap,const wxRect & rect,int flags,wxAlignment align,int indexAccel)668 void wxStdRenderer::DrawCheckButton(wxDC& dc,
669                                     const wxString& label,
670                                     const wxBitmap& bitmap,
671                                     const wxRect& rect,
672                                     int flags,
673                                     wxAlignment align,
674                                     int indexAccel)
675 {
676     if (bitmap.IsOk())
677         DrawCheckOrRadioButton(dc, label, bitmap, rect, flags, align, indexAccel);
678     else
679         DrawCheckOrRadioButton(dc, label, GetCheckBitmap(flags), rect, flags, align, indexAccel);
680 }
681 
DrawRadioButton(wxDC & dc,const wxString & label,const wxBitmap & bitmap,const wxRect & rect,int flags,wxAlignment align,int indexAccel)682 void wxStdRenderer::DrawRadioButton(wxDC& dc,
683                                     const wxString& label,
684                                     const wxBitmap& bitmap,
685                                     const wxRect& rect,
686                                     int flags,
687                                     wxAlignment align,
688                                     int indexAccel)
689 {
690     if (bitmap.IsOk())
691         DrawCheckOrRadioButton(dc, label, bitmap, rect, flags, align, indexAccel);
692     else
693         DrawCheckOrRadioButton(dc, label, GetRadioBitmap(flags), rect, flags, align, indexAccel);
694 
695 }
696 
DrawCheckOrRadioButton(wxDC & dc,const wxString & label,const wxBitmap & bitmap,const wxRect & rect,int flags,wxAlignment align,int indexAccel)697 void wxStdRenderer::DrawCheckOrRadioButton(wxDC& dc,
698                                            const wxString& label,
699                                            const wxBitmap& bitmap,
700                                            const wxRect& rect,
701                                            int flags,
702                                            wxAlignment align,
703                                            int indexAccel)
704 {
705     // calculate the position of the bitmap and of the label
706     wxCoord heightBmp = bitmap.GetHeight();
707     wxCoord xBmp,
708             yBmp = rect.y + (rect.height - heightBmp) / 2;
709 
710     wxRect rectLabel;
711     dc.GetMultiLineTextExtent(label, NULL, &rectLabel.height);
712     rectLabel.y = rect.y + (rect.height - rectLabel.height) / 2;
713 
714     // align label vertically with the bitmap - looks nicer like this
715     rectLabel.y -= (rectLabel.height - heightBmp) % 2;
716 
717     // calc horz position
718     if ( align == wxALIGN_RIGHT )
719     {
720         xBmp = rect.GetRight() - bitmap.GetWidth();
721         rectLabel.x = rect.x + 3;
722         rectLabel.SetRight(xBmp);
723     }
724     else // normal (checkbox to the left of the text) case
725     {
726         xBmp = rect.x;
727         rectLabel.x = xBmp + bitmap.GetWidth() + 5;
728         rectLabel.SetRight(rect.GetRight());
729     }
730 
731     dc.DrawBitmap(bitmap, xBmp, yBmp, true /* use mask */);
732 
733     DrawLabel(dc, label, rectLabel, flags,
734               wxALIGN_LEFT | wxALIGN_TOP, indexAccel);
735 }
736 
737 #if wxUSE_TEXTCTRL
738 
DrawTextLine(wxDC & dc,const wxString & text,const wxRect & rect,int selStart,int selEnd,int flags)739 void wxStdRenderer::DrawTextLine(wxDC& dc,
740                                  const wxString& text,
741                                  const wxRect& rect,
742                                  int selStart,
743                                  int selEnd,
744                                  int flags)
745 {
746     if ( (selStart == -1) || !(flags & wxCONTROL_FOCUSED) )
747     {
748         // just draw it as is
749         dc.DrawText(text, rect.x, rect.y);
750     }
751     else // we have selection
752     {
753         wxCoord width,
754                 x = rect.x;
755 
756         // draw the part before selection
757         wxString s(text, (size_t)selStart);
758         if ( !s.empty() )
759         {
760             dc.DrawText(s, x, rect.y);
761 
762             dc.GetTextExtent(s, &width, NULL);
763             x += width;
764         }
765 
766         // draw the selection itself
767         s = wxString(text.c_str() + selStart, text.c_str() + selEnd);
768         if ( !s.empty() )
769         {
770             wxColour colFg = dc.GetTextForeground(),
771                      colBg = dc.GetTextBackground();
772             dc.SetTextForeground(wxSCHEME_COLOUR(m_scheme, HIGHLIGHT_TEXT));
773             dc.SetTextBackground(wxSCHEME_COLOUR(m_scheme, HIGHLIGHT));
774             dc.SetBackgroundMode(wxBRUSHSTYLE_SOLID);
775 
776             dc.DrawText(s, x, rect.y);
777             dc.GetTextExtent(s, &width, NULL);
778             x += width;
779 
780             dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
781             dc.SetTextBackground(colBg);
782             dc.SetTextForeground(colFg);
783         }
784 
785         // draw the final part
786         s = text.c_str() + selEnd;
787         if ( !s.empty() )
788         {
789             dc.DrawText(s, x, rect.y);
790         }
791     }
792 }
793 
DrawLineWrapMark(wxDC & WXUNUSED (dc),const wxRect & WXUNUSED (rect))794 void wxStdRenderer::DrawLineWrapMark(wxDC& WXUNUSED(dc),
795                                      const wxRect& WXUNUSED(rect))
796 {
797     // nothing by default
798 }
799 
GetTextBorderWidth(const wxTextCtrl * WXUNUSED (text)) const800 int wxStdRenderer::GetTextBorderWidth(const wxTextCtrl * WXUNUSED(text)) const
801 {
802     return 1;
803 }
804 
805 wxRect
GetTextTotalArea(const wxTextCtrl * text,const wxRect & rect) const806 wxStdRenderer::GetTextTotalArea(const wxTextCtrl *text, const wxRect& rect) const
807 {
808     wxRect rectTotal = rect;
809     rectTotal.Inflate(GetTextBorderWidth(text));
810     return rectTotal;
811 }
812 
GetTextClientArea(const wxTextCtrl * text,const wxRect & rect,wxCoord * extraSpaceBeyond) const813 wxRect wxStdRenderer::GetTextClientArea(const wxTextCtrl *text,
814                                         const wxRect& rect,
815                                         wxCoord *extraSpaceBeyond) const
816 {
817     wxRect rectText = rect;
818     rectText.Deflate(GetTextBorderWidth(text));
819 
820     if ( extraSpaceBeyond )
821         *extraSpaceBeyond = 0;
822 
823     return rectText;
824 }
825 
826 #endif // wxUSE_TEXTCTRL
827 
828 // ----------------------------------------------------------------------------
829 // scrollbars drawing
830 // ----------------------------------------------------------------------------
831 
DrawScrollbarArrow(wxDC & dc,wxDirection dir,const wxRect & rect,int flags)832 void wxStdRenderer::DrawScrollbarArrow(wxDC& dc,
833                                        wxDirection dir,
834                                        const wxRect& rect,
835                                        int flags)
836 {
837     DrawArrow(dc, dir, rect, flags);
838 }
839 
DrawScrollCorner(wxDC & dc,const wxRect & rect)840 void wxStdRenderer::DrawScrollCorner(wxDC& dc, const wxRect& rect)
841 {
842     DrawSolidRect(dc, wxSCHEME_COLOUR(m_scheme, CONTROL), rect);
843 }
844 
845 // ----------------------------------------------------------------------------
846 // status bar
847 // ----------------------------------------------------------------------------
848 
849 #if wxUSE_STATUSBAR
850 
GetStatusBarBorders() const851 wxSize wxStdRenderer::GetStatusBarBorders() const
852 {
853     // Rendered border may be different depending on field's style, we use
854     // the largest value so that any field certainly fits into the borders
855     // we return:
856     wxRect raised = GetBorderDimensions(wxBORDER_RAISED);
857     wxRect flat = GetBorderDimensions(wxBORDER_STATIC);
858     wxASSERT_MSG( raised.x == raised.width && raised.y == raised.height &&
859                   flat.x == flat.width && flat.y == flat.height,
860                   wxT("this code expects uniform borders, you must override GetStatusBarBorders") );
861 
862     // take the larger of flat/raised values:
863     wxSize border(wxMax(raised.x, flat.x), wxMax(raised.y, flat.y));
864 
865     return border;
866 }
867 
GetStatusBarBorderBetweenFields() const868 wxCoord wxStdRenderer::GetStatusBarBorderBetweenFields() const
869 {
870     return 2;
871 }
872 
GetStatusBarFieldMargins() const873 wxSize wxStdRenderer::GetStatusBarFieldMargins() const
874 {
875     return wxSize(2, 2);
876 }
877 
DrawStatusField(wxDC & dc,const wxRect & rect,const wxString & label,int flags,int style)878 void wxStdRenderer::DrawStatusField(wxDC& dc,
879                                     const wxRect& rect,
880                                     const wxString& label,
881                                     int flags,
882                                     int style)
883 {
884     wxRect rectIn;
885 
886     if ( style == wxSB_RAISED )
887         DrawBorder(dc, wxBORDER_RAISED, rect, flags, &rectIn);
888     else if ( style != wxSB_FLAT )
889         DrawBorder(dc, wxBORDER_STATIC, rect, flags, &rectIn);
890     else
891         rectIn = rect;
892 
893     rectIn.Deflate(GetStatusBarFieldMargins());
894 
895     wxDCClipper clipper(dc, rectIn);
896     DrawLabel(dc, label, rectIn, flags, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL);
897 }
898 
899 #endif // wxUSE_STATUSBAR
900 
901 // ----------------------------------------------------------------------------
902 // top level windows
903 // ----------------------------------------------------------------------------
904 
HitTestFrame(const wxRect & rect,const wxPoint & pt,int flags) const905 int wxStdRenderer::HitTestFrame(const wxRect& rect, const wxPoint& pt, int flags) const
906 {
907     wxRect client = GetFrameClientArea(rect, flags);
908 
909     if ( client.Contains(pt) )
910         return wxHT_TOPLEVEL_CLIENT_AREA;
911 
912     if ( flags & wxTOPLEVEL_TITLEBAR )
913     {
914         wxRect client = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR);
915 
916         if ( flags & wxTOPLEVEL_ICON )
917         {
918             if ( wxRect(client.GetPosition(), GetFrameIconSize()).Contains(pt) )
919                 return wxHT_TOPLEVEL_ICON;
920         }
921 
922         wxRect btnRect(client.GetRight() - 2 - FRAME_BUTTON_WIDTH,
923                        client.GetTop() + (FRAME_TITLEBAR_HEIGHT-FRAME_BUTTON_HEIGHT)/2,
924                        FRAME_BUTTON_WIDTH, FRAME_BUTTON_HEIGHT);
925 
926         if ( flags & wxTOPLEVEL_BUTTON_CLOSE )
927         {
928             if ( btnRect.Contains(pt) )
929                 return wxHT_TOPLEVEL_BUTTON_CLOSE;
930             btnRect.x -= FRAME_BUTTON_WIDTH + 2;
931         }
932         if ( flags & wxTOPLEVEL_BUTTON_MAXIMIZE )
933         {
934             if ( btnRect.Contains(pt) )
935                 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE;
936             btnRect.x -= FRAME_BUTTON_WIDTH;
937         }
938         if ( flags & wxTOPLEVEL_BUTTON_RESTORE )
939         {
940             if ( btnRect.Contains(pt) )
941                 return wxHT_TOPLEVEL_BUTTON_RESTORE;
942             btnRect.x -= FRAME_BUTTON_WIDTH;
943         }
944         if ( flags & wxTOPLEVEL_BUTTON_ICONIZE )
945         {
946             if ( btnRect.Contains(pt) )
947                 return wxHT_TOPLEVEL_BUTTON_ICONIZE;
948             btnRect.x -= FRAME_BUTTON_WIDTH;
949         }
950         if ( flags & wxTOPLEVEL_BUTTON_HELP )
951         {
952             if ( btnRect.Contains(pt) )
953                 return wxHT_TOPLEVEL_BUTTON_HELP;
954             btnRect.x -= FRAME_BUTTON_WIDTH;
955         }
956 
957         if ( pt.y >= client.y && pt.y < client.y + FRAME_TITLEBAR_HEIGHT )
958             return wxHT_TOPLEVEL_TITLEBAR;
959     }
960 
961     if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) )
962     {
963         // we are certainly at one of borders, let's decide which one:
964 
965         int border = 0;
966         // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
967         if ( pt.x < client.x )
968             border |= wxHT_TOPLEVEL_BORDER_W;
969         else if ( pt.x >= client.width + client.x )
970             border |= wxHT_TOPLEVEL_BORDER_E;
971         if ( pt.y < client.y )
972             border |= wxHT_TOPLEVEL_BORDER_N;
973         else if ( pt.y >= client.height + client.y )
974             border |= wxHT_TOPLEVEL_BORDER_S;
975         return border;
976     }
977 
978     return wxHT_NOWHERE;
979 }
980 
DrawFrameTitleBar(wxDC & dc,const wxRect & rect,const wxString & title,const wxIcon & icon,int flags,int specialButton,int specialButtonFlags)981 void wxStdRenderer::DrawFrameTitleBar(wxDC& dc,
982                                       const wxRect& rect,
983                                       const wxString& title,
984                                       const wxIcon& icon,
985                                       int flags,
986                                       int specialButton,
987                                       int specialButtonFlags)
988 {
989     if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) )
990     {
991         DrawFrameBorder(dc, rect, flags);
992     }
993     if ( flags & wxTOPLEVEL_TITLEBAR )
994     {
995         DrawFrameBackground(dc, rect, flags);
996         if ( flags & wxTOPLEVEL_ICON )
997             DrawFrameIcon(dc, rect, icon, flags);
998         DrawFrameTitle(dc, rect, title, flags);
999 
1000         wxRect client = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR);
1001         wxCoord x,y;
1002         x = client.GetRight() - 2 - FRAME_BUTTON_WIDTH;
1003         y = client.GetTop() + (FRAME_TITLEBAR_HEIGHT-FRAME_BUTTON_HEIGHT)/2;
1004 
1005         if ( flags & wxTOPLEVEL_BUTTON_CLOSE )
1006         {
1007             DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_CLOSE,
1008                             (specialButton == wxTOPLEVEL_BUTTON_CLOSE) ?
1009                             specialButtonFlags : 0);
1010             x -= FRAME_BUTTON_WIDTH + 2;
1011         }
1012         if ( flags & wxTOPLEVEL_BUTTON_MAXIMIZE )
1013         {
1014             DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_MAXIMIZE,
1015                             (specialButton == wxTOPLEVEL_BUTTON_MAXIMIZE) ?
1016                             specialButtonFlags : 0);
1017             x -= FRAME_BUTTON_WIDTH;
1018         }
1019         if ( flags & wxTOPLEVEL_BUTTON_RESTORE )
1020         {
1021             DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_RESTORE,
1022                             (specialButton == wxTOPLEVEL_BUTTON_RESTORE) ?
1023                             specialButtonFlags : 0);
1024             x -= FRAME_BUTTON_WIDTH;
1025         }
1026         if ( flags & wxTOPLEVEL_BUTTON_ICONIZE )
1027         {
1028             DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_ICONIZE,
1029                             (specialButton == wxTOPLEVEL_BUTTON_ICONIZE) ?
1030                             specialButtonFlags : 0);
1031             x -= FRAME_BUTTON_WIDTH;
1032         }
1033         if ( flags & wxTOPLEVEL_BUTTON_HELP )
1034         {
1035             DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_HELP,
1036                             (specialButton == wxTOPLEVEL_BUTTON_HELP) ?
1037                             specialButtonFlags : 0);
1038         }
1039     }
1040 }
1041 
DrawFrameBorder(wxDC & dc,const wxRect & rect,int flags)1042 void wxStdRenderer::DrawFrameBorder(wxDC& dc, const wxRect& rect, int flags)
1043 {
1044     if ( !(flags & wxTOPLEVEL_BORDER) )
1045         return;
1046 
1047     wxRect r(rect);
1048 
1049     DrawAntiSunkenBorder(dc, &r);
1050     DrawExtraBorder(dc, &r);
1051     if ( flags & wxTOPLEVEL_RESIZEABLE )
1052         DrawExtraBorder(dc, &r);
1053 }
1054 
DrawFrameBackground(wxDC & dc,const wxRect & rect,int flags)1055 void wxStdRenderer::DrawFrameBackground(wxDC& dc, const wxRect& rect, int flags)
1056 {
1057     if ( !(flags & wxTOPLEVEL_TITLEBAR) )
1058         return;
1059 
1060     wxColour col = m_scheme->Get(flags & wxTOPLEVEL_ACTIVE
1061                                     ? wxColourScheme::TITLEBAR_ACTIVE
1062                                     : wxColourScheme::TITLEBAR);
1063 
1064     wxRect r = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR);
1065     r.height = FRAME_TITLEBAR_HEIGHT;
1066 
1067     DrawBackground(dc, col, r);
1068 }
1069 
DrawFrameTitle(wxDC & dc,const wxRect & rect,const wxString & title,int flags)1070 void wxStdRenderer::DrawFrameTitle(wxDC& dc,
1071                                    const wxRect& rect,
1072                                    const wxString& title,
1073                                    int flags)
1074 {
1075     wxColour col = m_scheme->Get(flags & wxTOPLEVEL_ACTIVE
1076                                     ? wxColourScheme::TITLEBAR_ACTIVE_TEXT
1077                                     : wxColourScheme::TITLEBAR_TEXT);
1078     dc.SetTextForeground(col);
1079 
1080     wxRect r = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR);
1081     r.height = FRAME_TITLEBAR_HEIGHT;
1082     if ( flags & wxTOPLEVEL_ICON )
1083     {
1084         r.x += FRAME_TITLEBAR_HEIGHT;
1085         r.width -= FRAME_TITLEBAR_HEIGHT + 2;
1086     }
1087     else
1088     {
1089         r.x += 1;
1090         r.width -= 3;
1091     }
1092 
1093     if ( flags & wxTOPLEVEL_BUTTON_CLOSE )
1094         r.width -= FRAME_BUTTON_WIDTH + 2;
1095     if ( flags & wxTOPLEVEL_BUTTON_MAXIMIZE )
1096         r.width -= FRAME_BUTTON_WIDTH;
1097     if ( flags & wxTOPLEVEL_BUTTON_RESTORE )
1098         r.width -= FRAME_BUTTON_WIDTH;
1099     if ( flags & wxTOPLEVEL_BUTTON_ICONIZE )
1100         r.width -= FRAME_BUTTON_WIDTH;
1101     if ( flags & wxTOPLEVEL_BUTTON_HELP )
1102         r.width -= FRAME_BUTTON_WIDTH;
1103 
1104     dc.SetFont(m_titlebarFont);
1105 
1106     wxString s;
1107     wxCoord textW;
1108     dc.GetTextExtent(title, &textW, NULL);
1109     if ( textW > r.width )
1110     {
1111         // text is too big, let's shorten it and add "..." after it:
1112         size_t len = title.length();
1113         wxCoord WSoFar, letterW;
1114 
1115         dc.GetTextExtent(wxT("..."), &WSoFar, NULL);
1116         if ( WSoFar > r.width )
1117         {
1118             // not enough space to draw anything
1119             return;
1120         }
1121 
1122         s.Alloc(len);
1123         for (size_t i = 0; i < len; i++)
1124         {
1125             dc.GetTextExtent(title[i], &letterW, NULL);
1126             if ( letterW + WSoFar > r.width )
1127                 break;
1128             WSoFar += letterW;
1129             s << title[i];
1130         }
1131         s << wxT("...");
1132     }
1133     else // no need to truncate the title
1134     {
1135         s = title;
1136     }
1137 
1138     dc.DrawLabel(s, wxNullBitmap, r, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL);
1139 }
1140 
DrawFrameIcon(wxDC & dc,const wxRect & rect,const wxIcon & icon,int flags)1141 void wxStdRenderer::DrawFrameIcon(wxDC& dc,
1142                                   const wxRect& rect,
1143                                   const wxIcon& icon,
1144                                   int flags)
1145 {
1146     if ( icon.IsOk() )
1147     {
1148         wxRect r = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR);
1149         dc.DrawIcon(icon, r.x, r.y);
1150     }
1151 }
1152 
DrawFrameButton(wxDC & dc,wxCoord x,wxCoord y,int button,int flags)1153 void wxStdRenderer::DrawFrameButton(wxDC& dc,
1154                                     wxCoord x, wxCoord y,
1155                                     int button,
1156                                     int flags)
1157 {
1158     FrameButtonType idx;
1159     switch (button)
1160     {
1161         case wxTOPLEVEL_BUTTON_CLOSE:    idx = FrameButton_Close; break;
1162         case wxTOPLEVEL_BUTTON_MAXIMIZE: idx = FrameButton_Maximize; break;
1163         case wxTOPLEVEL_BUTTON_ICONIZE:  idx = FrameButton_Minimize; break;
1164         case wxTOPLEVEL_BUTTON_RESTORE:  idx = FrameButton_Restore; break;
1165         case wxTOPLEVEL_BUTTON_HELP:     idx = FrameButton_Help; break;
1166         default:
1167             wxFAIL_MSG(wxT("incorrect button specification"));
1168             return;
1169     }
1170 
1171     wxBitmap bmp = GetFrameButtonBitmap(idx);
1172     if ( !bmp.IsOk() )
1173         return;
1174 
1175     wxRect rectBtn(x, y, FRAME_BUTTON_WIDTH, FRAME_BUTTON_HEIGHT);
1176     if ( flags & wxCONTROL_PRESSED )
1177     {
1178         DrawSunkenBorder(dc, &rectBtn);
1179 
1180         rectBtn.Offset(1, 1);
1181     }
1182     else
1183     {
1184         DrawRaisedBorder(dc, &rectBtn);
1185     }
1186 
1187     DrawBackground(dc, wxSCHEME_COLOUR(m_scheme, CONTROL), rectBtn);
1188 
1189     wxRect rectBmp(0, 0, bmp.GetWidth(), bmp.GetHeight());
1190     dc.DrawBitmap(bmp, rectBmp.CentreIn(rectBtn).GetPosition(), true);
1191 }
1192 
GetFrameBorderWidth(int flags) const1193 int wxStdRenderer::GetFrameBorderWidth(int flags) const
1194 {
1195     return flags & wxTOPLEVEL_RESIZEABLE ? 4 : 3;
1196 }
1197 
1198 
GetFrameClientArea(const wxRect & rect,int flags) const1199 wxRect wxStdRenderer::GetFrameClientArea(const wxRect& rect, int flags) const
1200 {
1201     wxRect r(rect);
1202 
1203     if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) )
1204     {
1205         r.Inflate(-GetFrameBorderWidth(flags));
1206     }
1207 
1208     if ( flags & wxTOPLEVEL_TITLEBAR )
1209     {
1210         r.y += FRAME_TITLEBAR_HEIGHT;
1211         r.height -= FRAME_TITLEBAR_HEIGHT;
1212     }
1213 
1214     return r;
1215 }
1216 
1217 wxSize
GetFrameTotalSize(const wxSize & clientSize,int flags) const1218 wxStdRenderer::GetFrameTotalSize(const wxSize& clientSize, int flags) const
1219 {
1220     wxSize s(clientSize);
1221 
1222     if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) )
1223     {
1224         s.IncBy(2*GetFrameBorderWidth(flags));
1225     }
1226 
1227     if ( flags & wxTOPLEVEL_TITLEBAR )
1228         s.y += FRAME_TITLEBAR_HEIGHT;
1229 
1230     return s;
1231 }
1232 
GetFrameMinSize(int flags) const1233 wxSize wxStdRenderer::GetFrameMinSize(int flags) const
1234 {
1235     wxSize s;
1236 
1237     if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) )
1238     {
1239         s.IncBy(2*GetFrameBorderWidth(flags));
1240     }
1241 
1242     if ( flags & wxTOPLEVEL_TITLEBAR )
1243     {
1244         s.y += FRAME_TITLEBAR_HEIGHT;
1245 
1246         if ( flags & wxTOPLEVEL_ICON )
1247             s.x += FRAME_TITLEBAR_HEIGHT + 2;
1248         if ( flags & wxTOPLEVEL_BUTTON_CLOSE )
1249             s.x += FRAME_BUTTON_WIDTH + 2;
1250         if ( flags & wxTOPLEVEL_BUTTON_MAXIMIZE )
1251             s.x += FRAME_BUTTON_WIDTH;
1252         if ( flags & wxTOPLEVEL_BUTTON_RESTORE )
1253             s.x += FRAME_BUTTON_WIDTH;
1254         if ( flags & wxTOPLEVEL_BUTTON_ICONIZE )
1255             s.x += FRAME_BUTTON_WIDTH;
1256         if ( flags & wxTOPLEVEL_BUTTON_HELP )
1257             s.x += FRAME_BUTTON_WIDTH;
1258     }
1259 
1260     return s;
1261 }
1262 
GetFrameIconSize() const1263 wxSize wxStdRenderer::GetFrameIconSize() const
1264 {
1265     return wxSize(16, 16);
1266 }
1267