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