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