]> git.saurik.com Git - wxWidgets.git/blob - src/osx/carbon/renderer.cpp
Fix setting tooltips for generic wxSpinCtrl.
[wxWidgets.git] / src / osx / carbon / renderer.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        src/osx/carbon/renderer.cpp
3 // Purpose:     implementation of wxRendererNative for Mac
4 // Author:      Vadim Zeitlin
5 // Modified by:
6 // Created:     20.07.2003
7 // RCS-ID:      $Id$
8 // Copyright:   (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
9 // Licence:     wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // for compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #if wxOSX_USE_COCOA_OR_CARBON
16
17 #ifdef __BORLANDC__
18     #pragma hdrstop
19 #endif
20
21 #ifndef WX_PRECOMP
22     #include "wx/string.h"
23     #include "wx/dc.h"
24     #include "wx/bitmap.h"
25     #include "wx/settings.h"
26     #include "wx/dcclient.h"
27     #include "wx/dcmemory.h"
28     #include "wx/toplevel.h"
29 #endif
30
31 #include "wx/renderer.h"
32 #include "wx/graphics.h"
33 #include "wx/dcgraph.h"
34 #include "wx/osx/private.h"
35
36 #ifdef wxHAS_DRAW_TITLE_BAR_BITMAP
37     #include "wx/image.h"
38     #include "wx/mstream.h"
39 #endif // wxHAS_DRAW_TITLE_BAR_BITMAP
40
41
42 // check if we're currently in a paint event
43 inline bool wxInPaintEvent(wxWindow* win, wxDC& dc)
44 {
45     return win->MacGetCGContextRef() != NULL ||
46            // wxMemoryDC's also have a valid CGContext.
47            dc.IsKindOf( CLASSINFO(wxMemoryDC) );
48 }
49
50
51
52 class WXDLLEXPORT wxRendererMac : public wxDelegateRendererNative
53 {
54 public:
55     // draw the header control button (used by wxListCtrl)
56     virtual int DrawHeaderButton( wxWindow *win,
57         wxDC& dc,
58         const wxRect& rect,
59         int flags = 0,
60         wxHeaderSortIconType sortArrow = wxHDR_SORT_ICON_NONE,
61         wxHeaderButtonParams* params = NULL );
62
63     virtual int GetHeaderButtonHeight(wxWindow *win);
64
65     virtual int GetHeaderButtonMargin(wxWindow *win);
66
67     // draw the expanded/collapsed icon for a tree control item
68     virtual void DrawTreeItemButton( wxWindow *win,
69         wxDC& dc,
70         const wxRect& rect,
71         int flags = 0 );
72
73     // draw a (vertical) sash
74     virtual void DrawSplitterSash( wxWindow *win,
75         wxDC& dc,
76         const wxSize& size,
77         wxCoord position,
78         wxOrientation orient,
79         int flags = 0 );
80
81     virtual void DrawCheckBox(wxWindow *win,
82                               wxDC& dc,
83                               const wxRect& rect,
84                               int flags = 0);
85
86     virtual wxSize GetCheckBoxSize(wxWindow* win);
87
88     virtual void DrawComboBoxDropButton(wxWindow *win,
89                                         wxDC& dc,
90                                         const wxRect& rect,
91                                         int flags = 0);
92
93     virtual void DrawPushButton(wxWindow *win,
94                                 wxDC& dc,
95                                 const wxRect& rect,
96                                 int flags = 0);
97
98     virtual void DrawItemSelectionRect(wxWindow *win,
99                                        wxDC& dc,
100                                        const wxRect& rect,
101                                        int flags = 0);
102
103     virtual void DrawFocusRect(wxWindow* win, wxDC& dc, const wxRect& rect, int flags = 0);
104
105     virtual void DrawChoice(wxWindow* win, wxDC& dc, const wxRect& rect, int flags=0);
106
107     virtual void DrawComboBox(wxWindow* win, wxDC& dc, const wxRect& rect, int flags=0);
108
109     virtual void DrawTextCtrl(wxWindow* win, wxDC& dc, const wxRect& rect, int flags=0);
110
111     virtual void DrawRadioBitmap(wxWindow* win, wxDC& dc, const wxRect& rect, int flags=0);
112
113 #ifdef wxHAS_DRAW_TITLE_BAR_BITMAP
114     virtual void DrawTitleBarBitmap(wxWindow *win,
115                                     wxDC& dc,
116                                     const wxRect& rect,
117                                     wxTitleBarButton button,
118                                     int flags = 0);
119 #endif // wxHAS_DRAW_TITLE_BAR_BITMAP
120
121 private:
122     void DrawMacThemeButton(wxWindow *win,
123                             wxDC& dc,
124                             const wxRect& rect,
125                             int flags,
126                             int kind,
127                             int adornment);
128
129     // the tree buttons
130     wxBitmap m_bmpTreeExpanded;
131     wxBitmap m_bmpTreeCollapsed;
132 };
133
134 // ============================================================================
135 // implementation
136 // ============================================================================
137
138 // static
139 wxRendererNative& wxRendererNative::GetDefault()
140 {
141     static wxRendererMac s_rendererMac;
142
143     return s_rendererMac;
144 }
145
146 int wxRendererMac::DrawHeaderButton( wxWindow *win,
147     wxDC& dc,
148     const wxRect& rect,
149     int flags,
150     wxHeaderSortIconType sortArrow,
151     wxHeaderButtonParams* params )
152 {
153     const wxCoord x = rect.x;
154     const wxCoord y = rect.y;
155     const wxCoord w = rect.width;
156     const wxCoord h = rect.height;
157
158     dc.SetBrush( *wxTRANSPARENT_BRUSH );
159
160     HIRect headerRect = CGRectMake( x, y, w, h );
161     if ( !wxInPaintEvent(win, dc) )
162     {
163         win->Refresh( &rect );
164     }
165     else
166     {
167         CGContextRef cgContext;
168         wxGCDCImpl *impl = (wxGCDCImpl*) dc.GetImpl();
169
170         cgContext = (CGContextRef) impl->GetGraphicsContext()->GetNativeContext();
171
172         {
173             HIThemeButtonDrawInfo drawInfo;
174             HIRect labelRect;
175
176             memset( &drawInfo, 0, sizeof(drawInfo) );
177             drawInfo.version = 0;
178             drawInfo.kind = kThemeListHeaderButton;
179             drawInfo.state = (flags & wxCONTROL_DISABLED) ? kThemeStateInactive : kThemeStateActive;
180             drawInfo.value = (flags & wxCONTROL_SELECTED) ? kThemeButtonOn : kThemeButtonOff;
181             drawInfo.adornment = kThemeAdornmentNone;
182
183             // The down arrow is drawn automatically, change it to an up arrow if needed.
184             if ( sortArrow == wxHDR_SORT_ICON_UP )
185                 drawInfo.adornment = kThemeAdornmentHeaderButtonSortUp;
186
187             HIThemeDrawButton( &headerRect, &drawInfo, cgContext, kHIThemeOrientationNormal, &labelRect );
188
189             // If we don't want any arrows we need to draw over the one already there
190             if ( (flags & wxCONTROL_SELECTED) && (sortArrow == wxHDR_SORT_ICON_NONE) )
191             {
192                 // clip to the header rectangle
193                 CGContextSaveGState( cgContext );
194                 CGContextClipToRect( cgContext, headerRect );
195                 // but draw bigger than that so the arrow will get clipped off
196                 headerRect.size.width += 25;
197                 HIThemeDrawButton( &headerRect, &drawInfo, cgContext, kHIThemeOrientationNormal, &labelRect );
198                 CGContextRestoreGState( cgContext );
199             }
200         }
201     }
202
203     // Reserve room for the arrows before writing the label, and turn off the
204     // flags we've already handled
205     wxRect newRect(rect);
206     if ( (flags & wxCONTROL_SELECTED) && (sortArrow != wxHDR_SORT_ICON_NONE) )
207     {
208         newRect.width -= 12;
209         sortArrow = wxHDR_SORT_ICON_NONE;
210     }
211     flags &= ~wxCONTROL_SELECTED;
212
213     return DrawHeaderButtonContents(win, dc, newRect, flags, sortArrow, params);
214 }
215
216
217 int wxRendererMac::GetHeaderButtonHeight(wxWindow* WXUNUSED(win))
218 {
219     SInt32      standardHeight;
220     OSStatus        errStatus;
221
222     errStatus = GetThemeMetric( kThemeMetricListHeaderHeight, &standardHeight );
223     if (errStatus == noErr)
224     {
225         return standardHeight;
226     }
227     return -1;
228 }
229
230 int wxRendererMac::GetHeaderButtonMargin(wxWindow *WXUNUSED(win))
231 {
232     wxFAIL_MSG( "GetHeaderButtonMargin() not implemented" );
233     return -1;
234 }
235
236 void wxRendererMac::DrawTreeItemButton( wxWindow *win,
237     wxDC& dc,
238     const wxRect& rect,
239     int flags )
240 {
241     // now the wxGCDC is using native transformations
242     const wxCoord x = rect.x;
243     const wxCoord y = rect.y;
244     const wxCoord w = rect.width;
245     const wxCoord h = rect.height;
246
247     dc.SetBrush( *wxTRANSPARENT_BRUSH );
248
249     HIRect headerRect = CGRectMake( x, y, w, h );
250     if ( !wxInPaintEvent(win, dc) )
251     {
252         win->Refresh( &rect );
253     }
254     else
255     {
256         CGContextRef cgContext;
257
258         wxGCDCImpl *impl = (wxGCDCImpl*) dc.GetImpl();
259         cgContext = (CGContextRef) impl->GetGraphicsContext()->GetNativeContext();
260
261         HIThemeButtonDrawInfo drawInfo;
262         HIRect labelRect;
263
264         memset( &drawInfo, 0, sizeof(drawInfo) );
265         drawInfo.version = 0;
266         drawInfo.kind = kThemeDisclosureButton;
267         drawInfo.state = (flags & wxCONTROL_DISABLED) ? kThemeStateInactive : kThemeStateActive;
268         // Apple mailing list posts say to use the arrow adornment constants, but those don't work.
269         // We need to set the value using the 'old' DrawThemeButton constants instead.
270         drawInfo.value = (flags & wxCONTROL_EXPANDED) ? kThemeDisclosureDown : kThemeDisclosureRight;
271         drawInfo.adornment = kThemeAdornmentNone;
272
273         HIThemeDrawButton( &headerRect, &drawInfo, cgContext, kHIThemeOrientationNormal, &labelRect );
274     }
275 }
276
277 void wxRendererMac::DrawSplitterSash( wxWindow *win,
278     wxDC& dc,
279     const wxSize& size,
280     wxCoord position,
281     wxOrientation orient,
282     int WXUNUSED(flags) )
283 {
284     bool hasMetal = win->MacGetTopLevelWindow()->GetExtraStyle() & wxFRAME_EX_METAL;
285     SInt32 height;
286     GetThemeMetric( kThemeMetricSmallPaneSplitterHeight, &height );
287     HIRect splitterRect;
288     if (orient == wxVERTICAL)
289         splitterRect = CGRectMake( position, 0, height, size.y );
290     else
291         splitterRect = CGRectMake( 0, position, size.x, height );
292
293     // under compositing we should only draw when called by the OS, otherwise just issue a redraw command
294     // strange redraw errors occur if we don't do this
295
296     if ( !wxInPaintEvent(win, dc) )
297     {
298         wxRect rect( (int) splitterRect.origin.x, (int) splitterRect.origin.y, (int) splitterRect.size.width,
299                      (int) splitterRect.size.height );
300         win->RefreshRect( rect );
301     }
302     else
303     {
304         CGContextRef cgContext;
305         wxGCDCImpl *impl = (wxGCDCImpl*) dc.GetImpl();
306         cgContext = (CGContextRef) impl->GetGraphicsContext()->GetNativeContext();
307
308         HIThemeBackgroundDrawInfo bgdrawInfo;
309         bgdrawInfo.version = 0;
310         bgdrawInfo.state = kThemeStateActive;
311         bgdrawInfo.kind = hasMetal ? kThemeBackgroundMetal : kThemeBackgroundPlacard;
312
313         if ( hasMetal )
314             HIThemeDrawBackground(&splitterRect, &bgdrawInfo, cgContext, kHIThemeOrientationNormal);
315         else
316         {
317             CGContextSetFillColorWithColor(cgContext,win->GetBackgroundColour().GetCGColor());
318             CGContextFillRect(cgContext,splitterRect);
319         }
320
321         HIThemeSplitterDrawInfo drawInfo;
322         drawInfo.version = 0;
323         drawInfo.state = kThemeStateActive;
324         drawInfo.adornment = hasMetal ? kHIThemeSplitterAdornmentMetal : kHIThemeSplitterAdornmentNone;
325         HIThemeDrawPaneSplitter( &splitterRect, &drawInfo, cgContext, kHIThemeOrientationNormal );
326     }
327 }
328
329 void
330 wxRendererMac::DrawItemSelectionRect(wxWindow * WXUNUSED(win),
331                                      wxDC& dc,
332                                      const wxRect& rect,
333                                      int flags)
334 {
335     if ( !(flags & wxCONTROL_SELECTED) )
336         return;
337
338     wxColour col( wxMacCreateCGColorFromHITheme( (flags & wxCONTROL_FOCUSED) ?
339                                                  kThemeBrushAlternatePrimaryHighlightColor
340                                                                              : kThemeBrushSecondaryHighlightColor ) );
341     wxBrush selBrush( col );
342
343     dc.SetPen( *wxTRANSPARENT_PEN );
344     dc.SetBrush( selBrush );
345     dc.DrawRectangle( rect );
346 }
347
348
349 void
350 wxRendererMac::DrawMacThemeButton(wxWindow *win,
351                                   wxDC& dc,
352                                   const wxRect& rect,
353                                   int flags,
354                                   int kind,
355                                   int adornment)
356 {
357     // now the wxGCDC is using native transformations
358     const wxCoord x = rect.x;
359     const wxCoord y = rect.y;
360     const wxCoord w = rect.width;
361     const wxCoord h = rect.height;
362
363     dc.SetBrush( *wxTRANSPARENT_BRUSH );
364
365     HIRect headerRect = CGRectMake( x, y, w, h );
366     if ( !wxInPaintEvent(win, dc) )
367     {
368         win->Refresh( &rect );
369     }
370     else
371     {
372         wxGCDCImpl *impl = (wxGCDCImpl*) dc.GetImpl();
373         CGContextRef cgContext;
374         cgContext = (CGContextRef) impl->GetGraphicsContext()->GetNativeContext();
375
376         HIThemeButtonDrawInfo drawInfo;
377         HIRect labelRect;
378
379         memset( &drawInfo, 0, sizeof(drawInfo) );
380         drawInfo.version = 0;
381         drawInfo.kind = kind;
382         drawInfo.state = (flags & wxCONTROL_DISABLED) ? kThemeStateInactive : kThemeStateActive;
383         drawInfo.value = (flags & wxCONTROL_SELECTED) ? kThemeButtonOn : kThemeButtonOff;
384         if (flags & wxCONTROL_UNDETERMINED)
385             drawInfo.value = kThemeButtonMixed;
386         drawInfo.adornment = adornment;
387         if (flags & wxCONTROL_FOCUSED)
388             drawInfo.adornment |= kThemeAdornmentFocus;
389
390         HIThemeDrawButton( &headerRect, &drawInfo, cgContext, kHIThemeOrientationNormal, &labelRect );
391     }
392 }
393
394 void
395 wxRendererMac::DrawCheckBox(wxWindow *win,
396                             wxDC& dc,
397                             const wxRect& rect,
398                             int flags)
399 {
400     if (flags & wxCONTROL_CHECKED)
401         flags |= wxCONTROL_SELECTED;
402
403     int kind;
404
405     if (win->GetWindowVariant() == wxWINDOW_VARIANT_SMALL ||
406         (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_SMALL))
407         kind = kThemeCheckBoxSmall;
408     else if (win->GetWindowVariant() == wxWINDOW_VARIANT_MINI ||
409              (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_MINI))
410         kind = kThemeCheckBoxMini;
411     else
412         kind = kThemeCheckBox;
413
414
415     DrawMacThemeButton(win, dc, rect, flags,
416                        kind, kThemeAdornmentNone);
417 }
418
419 wxSize wxRendererMac::GetCheckBoxSize(wxWindow* WXUNUSED(win))
420 {
421     wxSize size;
422     SInt32 width, height;
423     OSStatus errStatus;
424
425     errStatus = GetThemeMetric(kThemeMetricCheckBoxWidth, &width);
426     if (errStatus == noErr)
427     {
428         size.SetWidth(width);
429     }
430
431     errStatus = GetThemeMetric(kThemeMetricCheckBoxHeight, &height);
432     if (errStatus == noErr)
433     {
434         size.SetHeight(height);
435     }
436
437     return size;
438 }
439
440 void
441 wxRendererMac::DrawComboBoxDropButton(wxWindow *win,
442                               wxDC& dc,
443                               const wxRect& rect,
444                               int flags)
445 {
446     int kind;
447     if (win->GetWindowVariant() == wxWINDOW_VARIANT_SMALL || (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_SMALL))
448         kind = kThemeArrowButtonSmall;
449     else if (win->GetWindowVariant() == wxWINDOW_VARIANT_MINI || (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_MINI))
450         kind = kThemeArrowButtonMini;
451     else
452         kind = kThemeArrowButton;
453
454     DrawMacThemeButton(win, dc, rect, flags,
455                        kind, kThemeAdornmentArrowDownArrow);
456 }
457
458 void
459 wxRendererMac::DrawPushButton(wxWindow *win,
460                               wxDC& dc,
461                               const wxRect& rect,
462                               int flags)
463 {
464     int kind;
465     if (win->GetWindowVariant() == wxWINDOW_VARIANT_SMALL || (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_SMALL))
466         kind = kThemeBevelButtonSmall;
467     // There is no kThemeBevelButtonMini, but in this case, use Small
468     else if (win->GetWindowVariant() == wxWINDOW_VARIANT_MINI || (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_MINI))
469         kind = kThemeBevelButtonSmall;
470     else
471         kind = kThemeBevelButton;
472
473     DrawMacThemeButton(win, dc, rect, flags,
474                        kind, kThemeAdornmentNone);
475 }
476
477 void
478 wxRendererMac::DrawFocusRect(wxWindow* win, wxDC& dc, const wxRect& rect, int flags)
479 {
480     if (!win)
481     {
482         wxDelegateRendererNative::DrawFocusRect(win, dc, rect, flags);
483         return;
484     }
485
486     CGRect cgrect = CGRectMake( rect.x , rect.y , rect.width, rect.height ) ;
487
488     HIThemeFrameDrawInfo info ;
489
490     memset( &info, 0 , sizeof(info) ) ;
491
492     info.version = 0 ;
493     info.kind = 0 ;
494     info.state = kThemeStateActive;
495     info.isFocused = true ;
496
497     CGContextRef cgContext = (CGContextRef) win->MacGetCGContextRef() ;
498     wxASSERT( cgContext ) ;
499
500     HIThemeDrawFocusRect( &cgrect , true , cgContext , kHIThemeOrientationNormal ) ;
501 }
502
503 void wxRendererMac::DrawChoice(wxWindow* win, wxDC& dc,
504                            const wxRect& rect, int flags)
505 {
506     int kind;
507
508     if (win->GetWindowVariant() == wxWINDOW_VARIANT_SMALL ||
509         (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_SMALL))
510         kind = kThemePopupButtonSmall;
511     else if (win->GetWindowVariant() == wxWINDOW_VARIANT_MINI ||
512              (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_MINI))
513         kind = kThemePopupButtonMini;
514     else
515         kind = kThemePopupButton;
516
517     DrawMacThemeButton(win, dc, rect, flags, kind, kThemeAdornmentNone);
518 }
519
520
521 void wxRendererMac::DrawComboBox(wxWindow* win, wxDC& dc,
522                              const wxRect& rect, int flags)
523 {
524     int kind;
525
526     if (win->GetWindowVariant() == wxWINDOW_VARIANT_SMALL ||
527         (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_SMALL))
528         kind = kThemeComboBoxSmall;
529     else if (win->GetWindowVariant() == wxWINDOW_VARIANT_MINI ||
530              (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_MINI))
531         kind = kThemeComboBoxMini;
532     else
533         kind = kThemeComboBox;
534
535     DrawMacThemeButton(win, dc, rect, flags, kind, kThemeAdornmentNone);
536 }
537
538 void wxRendererMac::DrawRadioBitmap(wxWindow* win, wxDC& dc,
539                                 const wxRect& rect, int flags)
540 {
541     int kind;
542
543     if (win->GetWindowVariant() == wxWINDOW_VARIANT_SMALL ||
544         (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_SMALL))
545         kind = kThemeRadioButtonSmall;
546     else if (win->GetWindowVariant() == wxWINDOW_VARIANT_MINI ||
547              (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_MINI))
548         kind = kThemeRadioButtonMini;
549     else
550         kind = kThemeRadioButton;
551
552     if (flags & wxCONTROL_CHECKED)
553         flags |= wxCONTROL_SELECTED;
554
555     DrawMacThemeButton(win, dc, rect, flags,
556                           kind, kThemeAdornmentNone);
557 }
558
559 void wxRendererMac::DrawTextCtrl(wxWindow* win, wxDC& dc,
560                              const wxRect& rect, int flags)
561 {
562     const wxCoord x = rect.x;
563     const wxCoord y = rect.y;
564     const wxCoord w = rect.width;
565     const wxCoord h = rect.height;
566
567     dc.SetBrush( *wxWHITE_BRUSH );
568     dc.SetPen( *wxTRANSPARENT_PEN );
569     dc.DrawRectangle(rect);
570
571     dc.SetBrush( *wxTRANSPARENT_BRUSH );
572
573     HIRect hiRect = CGRectMake( x, y, w, h );
574     if ( !wxInPaintEvent(win, dc) )
575     {
576         win->Refresh( &rect );
577     }
578     else
579     {
580         CGContextRef cgContext;
581
582         cgContext = (CGContextRef) static_cast<wxGCDCImpl*>(dc.GetImpl())->GetGraphicsContext()->GetNativeContext();
583
584         {
585             HIThemeFrameDrawInfo drawInfo;
586
587             memset( &drawInfo, 0, sizeof(drawInfo) );
588             drawInfo.version = 0;
589             drawInfo.kind = kHIThemeFrameTextFieldSquare;
590             drawInfo.state = (flags & wxCONTROL_DISABLED) ? kThemeStateInactive : kThemeStateActive;
591             if (flags & wxCONTROL_FOCUSED)
592                 drawInfo.isFocused = true;
593
594             HIThemeDrawFrame( &hiRect, &drawInfo, cgContext, kHIThemeOrientationNormal);
595         }
596     }
597 }
598
599 #ifdef wxHAS_DRAW_TITLE_BAR_BITMAP
600
601 void wxRendererMac::DrawTitleBarBitmap(wxWindow *win,
602                                        wxDC& dc,
603                                        const wxRect& rect,
604                                        wxTitleBarButton button,
605                                        int flags)
606 {
607     // the files below were converted from the originals in art/osx/close*.png
608     // using misc/scripts/png2c.py script -- we must use PNG and not XPM for
609     // them because they use transparency and don't look right without it
610
611     /* close.png - 400 bytes */
612     static const unsigned char close_png[] = {
613       0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,
614       0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
615       0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0e,
616       0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0x48, 0x2d,
617       0xd1, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4b, 0x47,
618       0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0,
619       0xbd, 0xa7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70,
620       0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x12, 0x00,
621       0x00, 0x0b, 0x12, 0x01, 0xd2, 0xdd, 0x7e, 0xfc,
622       0x00, 0x00, 0x00, 0x09, 0x76, 0x70, 0x41, 0x67,
623       0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0e,
624       0x00, 0xb1, 0x5b, 0xf1, 0xf7, 0x00, 0x00, 0x00,
625       0xef, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0xa5,
626       0xd2, 0x31, 0x4a, 0x03, 0x41, 0x18, 0xc5, 0xf1,
627       0xdf, 0xc6, 0x55, 0x02, 0xb2, 0x18, 0xb0, 0x33,
628       0x8d, 0xd8, 0x6e, 0x8a, 0x14, 0xa6, 0xb2, 0xc9,
629       0x21, 0x72, 0x0b, 0xdb, 0x5c, 0x45, 0x98, 0x3b,
630       0x24, 0xc7, 0x99, 0x6d, 0x2d, 0x04, 0xd3, 0x09,
631       0x42, 0x48, 0x65, 0x60, 0x6c, 0x76, 0x65, 0x1c,
632       0x14, 0x45, 0x5f, 0x35, 0xfc, 0xe7, 0x3d, 0xe6,
633       0x9b, 0x8f, 0x57, 0xf9, 0xac, 0x06, 0x97, 0x98,
634       0xe0, 0xbc, 0x67, 0x07, 0xbc, 0xe2, 0x05, 0xfb,
635       0xc1, 0x58, 0x65, 0xa1, 0x2b, 0x4c, 0xb3, 0x40,
636       0xa9, 0x03, 0x9e, 0xb1, 0x83, 0x93, 0x2c, 0x74,
637       0x83, 0xb1, 0xef, 0x75, 0x86, 0x0b, 0x1c, 0xb1,
638       0x1f, 0xf5, 0xe3, 0x4d, 0x51, 0x43, 0x08, 0xe1,
639       0xb6, 0x4c, 0x64, 0xac, 0xee, 0xbd, 0x0d, 0x5c,
640       0x63, 0x89, 0x65, 0x08, 0x61, 0x9d, 0x52, 0x4a,
641       0x31, 0xc6, 0xcd, 0xc0, 0x62, 0x8c, 0x9b, 0x94,
642       0x52, 0x0a, 0x21, 0xac, 0x07, 0xd6, 0x67, 0xcc,
643       0x33, 0xf0, 0x61, 0x8c, 0x31, 0x6e, 0xf2, 0x73,
644       0xee, 0xc1, 0xbc, 0xc2, 0x1d, 0x4e, 0xf3, 0xd1,
645       0x62, 0x8c, 0xf7, 0x6d, 0xdb, 0xae, 0xa0, 0xeb,
646       0xba, 0xed, 0x6c, 0x36, 0x7b, 0x28, 0xa6, 0x7f,
647       0x1b, 0xf9, 0xa3, 0xea, 0x7e, 0xcd, 0x93, 0xf2,
648       0xb5, 0xae, 0xeb, 0xb6, 0xd0, 0xb6, 0xed, 0x2a,
649       0xc6, 0xa8, 0x78, 0xf5, 0xf0, 0xaf, 0xe5, 0x34,
650       0x58, 0xe4, 0xe1, 0x62, 0x11, 0x25, 0x5b, 0xa0,
651       0x19, 0x9a, 0x33, 0x14, 0xa0, 0xfe, 0xe1, 0x6b,
652       0x47, 0x3c, 0x62, 0x37, 0x34, 0x67, 0xdf, 0xc3,
653       0x71, 0xdf, 0x90, 0xaf, 0x74, 0xc0, 0x93, 0xbe,
654       0x72, 0x55, 0x71, 0xf9, 0xeb, 0x92, 0xbf, 0x03,
655       0x70, 0x33, 0x76, 0x58, 0xe5, 0x41, 0xfb, 0x6d,
656       0x00, 0x00, 0x00, 0x20, 0x7a, 0x54, 0x58, 0x74,
657       0x74, 0x69, 0x66, 0x66, 0x3a, 0x72, 0x6f, 0x77,
658       0x73, 0x2d, 0x70, 0x65, 0x72, 0x2d, 0x73, 0x74,
659       0x72, 0x69, 0x70, 0x00, 0x00, 0x78, 0xda, 0x33,
660       0xb5, 0x30, 0x05, 0x00, 0x01, 0x47, 0x00, 0xa3,
661       0x38, 0xda, 0x77, 0x3b, 0x00, 0x00, 0x00, 0x00,
662       0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
663     };
664
665     /* close_current.png - 421 bytes */
666     static const unsigned char close_current_png[] = {
667       0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,
668       0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
669       0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0e,
670       0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0x48, 0x2d,
671       0xd1, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4b, 0x47,
672       0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0,
673       0xbd, 0xa7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70,
674       0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x12, 0x00,
675       0x00, 0x0b, 0x12, 0x01, 0xd2, 0xdd, 0x7e, 0xfc,
676       0x00, 0x00, 0x00, 0x09, 0x76, 0x70, 0x41, 0x67,
677       0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0e,
678       0x00, 0xb1, 0x5b, 0xf1, 0xf7, 0x00, 0x00, 0x01,
679       0x04, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x9d,
680       0xd2, 0xbd, 0x4a, 0x43, 0x31, 0x00, 0xc5, 0xf1,
681       0xdf, 0x8d, 0x56, 0x44, 0x04, 0x45, 0xd0, 0xc5,
682       0x55, 0xdc, 0x0a, 0x8e, 0xed, 0xec, 0xe4, 0xec,
683       0x24, 0xd4, 0x67, 0x29, 0x59, 0xfa, 0x16, 0x9d,
684       0x7c, 0x07, 0x1d, 0x5c, 0xba, 0xa5, 0xa3, 0x28,
685       0x22, 0x94, 0xae, 0x2e, 0x1d, 0x4a, 0x5d, 0x55,
686       0xb8, 0x2e, 0x09, 0x5c, 0x4b, 0xfd, 0xa0, 0x67,
687       0x0a, 0x27, 0x39, 0xc9, 0x49, 0xf2, 0xaf, 0x7c,
688       0xd7, 0x01, 0x8e, 0x71, 0x84, 0xfd, 0xec, 0x2d,
689       0x30, 0xc3, 0x2b, 0xe6, 0x65, 0x61, 0xd5, 0x08,
690       0x9d, 0xe0, 0x14, 0x7b, 0x56, 0xeb, 0x0d, 0x13,
691       0x4c, 0x61, 0xa3, 0x11, 0x3a, 0xc3, 0x8e, 0x9f,
692       0xb5, 0x9d, 0x9b, 0xbc, 0x63, 0x1e, 0x72, 0xbd,
693       0x53, 0xb4, 0x20, 0xc6, 0xd8, 0x5e, 0x4e, 0x34,
694       0xbc, 0x56, 0x5e, 0x7b, 0x00, 0x6d, 0x5c, 0xe1,
695       0x2a, 0xc6, 0x38, 0xa8, 0xeb, 0xba, 0x4e, 0x29,
696       0xdd, 0x16, 0x2f, 0xa5, 0x74, 0x5b, 0xd7, 0x75,
697       0x1d, 0x63, 0x1c, 0x14, 0x0f, 0xed, 0x0a, 0xe7,
698       0xb9, 0x02, 0x48, 0x29, 0x5d, 0x77, 0x3a, 0x9d,
699       0x8b, 0xf1, 0x78, 0x7c, 0x07, 0x65, 0xdc, 0xed,
700       0x76, 0x6f, 0x1a, 0x25, 0x66, 0x15, 0x2e, 0xb1,
701       0xd5, 0xac, 0x56, 0xc2, 0xb0, 0x22, 0x04, 0xef,
702       0xc1, 0x9a, 0xda, 0xcc, 0xff, 0xf4, 0x6b, 0xd5,
703       0x94, 0x92, 0xa5, 0x53, 0x17, 0x6b, 0x3f, 0xce,
704       0x06, 0x3e, 0x71, 0x88, 0xed, 0xd1, 0x68, 0x34,
705       0x0b, 0x21, 0x4c, 0x7a, 0xbd, 0xde, 0x7d, 0xd9,
706       0x7a, 0x38, 0x1c, 0x3e, 0x86, 0x10, 0x26, 0xfd,
707       0x7e, 0xff, 0xa9, 0x01, 0xc2, 0x4b, 0x21, 0xa7,
708       0x00, 0xd0, 0xfa, 0xe3, 0x6a, 0x1f, 0x78, 0xc0,
709       0xb4, 0x90, 0x33, 0xcf, 0x44, 0xec, 0x66, 0x42,
710       0x56, 0xe9, 0x0d, 0xcf, 0x32, 0x72, 0xd5, 0xd2,
711       0xe4, 0xbf, 0x21, 0xff, 0x02, 0x4d, 0xb5, 0x74,
712       0x79, 0x60, 0x9f, 0x78, 0x78, 0x00, 0x00, 0x00,
713       0x20, 0x7a, 0x54, 0x58, 0x74, 0x74, 0x69, 0x66,
714       0x66, 0x3a, 0x72, 0x6f, 0x77, 0x73, 0x2d, 0x70,
715       0x65, 0x72, 0x2d, 0x73, 0x74, 0x72, 0x69, 0x70,
716       0x00, 0x00, 0x78, 0xda, 0x33, 0xb5, 0x30, 0x05,
717       0x00, 0x01, 0x47, 0x00, 0xa3, 0x38, 0xda, 0x77,
718       0x3b, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e,
719       0x44, 0xae, 0x42, 0x60, 0x82};
720
721     /* close_pressed.png - 458 bytes */
722     static const unsigned char close_pressed_png[] = {
723       0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,
724       0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
725       0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0e,
726       0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0x48, 0x2d,
727       0xd1, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4b, 0x47,
728       0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0,
729       0xbd, 0xa7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70,
730       0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x12, 0x00,
731       0x00, 0x0b, 0x12, 0x01, 0xd2, 0xdd, 0x7e, 0xfc,
732       0x00, 0x00, 0x00, 0x09, 0x76, 0x70, 0x41, 0x67,
733       0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0e,
734       0x00, 0xb1, 0x5b, 0xf1, 0xf7, 0x00, 0x00, 0x01,
735       0x29, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x9d,
736       0x92, 0x31, 0x6a, 0xc3, 0x40, 0x14, 0x44, 0x9f,
737       0x2c, 0xe1, 0xc2, 0x10, 0x08, 0xc4, 0xe0, 0x22,
738       0x76, 0x21, 0x04, 0x29, 0x13, 0xf0, 0x05, 0x54,
739       0xa5, 0x8a, 0x0f, 0xb2, 0x8d, 0x0e, 0xa0, 0x23,
740       0xa8, 0x56, 0xa3, 0x03, 0xe8, 0x08, 0xba, 0x80,
741       0xba, 0xb0, 0x45, 0x0a, 0x97, 0x02, 0x23, 0x58,
742       0x83, 0x40, 0x60, 0x61, 0x08, 0x11, 0x04, 0x57,
743       0x69, 0xf6, 0xc3, 0x46, 0x38, 0x24, 0x64, 0xca,
744       0xd9, 0x19, 0xe6, 0xff, 0xfd, 0xe3, 0xf1, 0x1d,
745       0x2b, 0x20, 0x02, 0x36, 0xc0, 0xd2, 0x72, 0x27,
746       0xe0, 0x08, 0x1c, 0x80, 0x5e, 0x84, 0x9e, 0x63,
747       0x7a, 0x04, 0xb6, 0xc0, 0x1d, 0xd7, 0x31, 0x00,
748       0x6f, 0xc0, 0x1e, 0xc0, 0x77, 0x4c, 0x31, 0x70,
749       0xc3, 0xcf, 0x58, 0xd8, 0x49, 0x3e, 0x81, 0x7e,
750       0x66, 0xc7, 0xdb, 0x02, 0x73, 0x80, 0xdd, 0x6e,
751       0xb7, 0x9a, 0x3a, 0x1c, 0x6e, 0x6e, 0xb5, 0x2b,
752       0x1f, 0x78, 0x02, 0x1e, 0x44, 0x90, 0x65, 0xd9,
753       0x8b, 0xef, 0xfb, 0xef, 0x5a, 0xeb, 0x33, 0x40,
754       0x92, 0x24, 0x51, 0x9a, 0xa6, 0xcf, 0xc6, 0x98,
755       0xae, 0x69, 0x9a, 0xd1, 0x26, 0x8f, 0x81, 0x8d,
756       0x07, 0xa0, 0xaa, 0xaa, 0x3e, 0x0c, 0xc3, 0x5a,
757       0x29, 0x15, 0x0b, 0xa7, 0x94, 0x8a, 0x8b, 0xa2,
758       0xa8, 0xab, 0xaa, 0xea, 0x9d, 0x21, 0x36, 0x81,
759       0xf3, 0x7b, 0x00, 0xe4, 0x79, 0x7e, 0x10, 0x03,
760       0x40, 0x51, 0x14, 0xb5, 0x70, 0x0e, 0x96, 0x33,
761       0xfe, 0x89, 0xc0, 0xde, 0x69, 0x2d, 0x44, 0x92,
762       0x24, 0x91, 0x8c, 0xe7, 0x26, 0x4f, 0x52, 0x4f,
763       0x81, 0x3d, 0xee, 0x5a, 0x3e, 0x47, 0x4c, 0xae,
764       0x50, 0x29, 0x15, 0xb7, 0x6d, 0xfb, 0xe1, 0xec,
765       0x79, 0xf4, 0x81, 0x0b, 0x70, 0x0f, 0x2c, 0x9a,
766       0xa6, 0x19, 0x8d, 0x31, 0x5d, 0x59, 0x96, 0x47,
767       0x31, 0x69, 0xad, 0xcf, 0xc6, 0x98, 0xce, 0x31,
768       0x0d, 0x80, 0x96, 0xe6, 0x48, 0x01, 0xe6, 0xbf,
769       0xac, 0x76, 0x01, 0x6a, 0x60, 0x2f, 0xcd, 0xe9,
770       0x6d, 0x23, 0x6e, 0xed, 0x9d, 0xae, 0x61, 0x00,
771       0x5e, 0xb1, 0x95, 0xf3, 0x26, 0x8f, 0x7f, 0x2e,
772       0xf9, 0x17, 0x50, 0x59, 0x74, 0x13, 0x34, 0x41,
773       0x04, 0x5a, 0x00, 0x00, 0x00, 0x20, 0x7a, 0x54,
774       0x58, 0x74, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x72,
775       0x6f, 0x77, 0x73, 0x2d, 0x70, 0x65, 0x72, 0x2d,
776       0x73, 0x74, 0x72, 0x69, 0x70, 0x00, 0x00, 0x78,
777       0xda, 0x33, 0xb5, 0x30, 0x05, 0x00, 0x01, 0x47,
778       0x00, 0xa3, 0x38, 0xda, 0x77, 0x3b, 0x00, 0x00,
779       0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42,
780       0x60, 0x82};
781
782     // currently we only support the close bitmap here
783     if ( button != wxTITLEBAR_BUTTON_CLOSE )
784     {
785         m_rendererNative.DrawTitleBarBitmap(win, dc, rect, button, flags);
786         return;
787     }
788
789     // choose the correct image depending on flags
790     const void *data;
791     size_t len;
792
793     if ( flags & wxCONTROL_PRESSED )
794     {
795         data = close_pressed_png;
796         len = WXSIZEOF(close_pressed_png);
797     }
798     else if ( flags & wxCONTROL_CURRENT )
799     {
800         data = close_current_png;
801         len = WXSIZEOF(close_current_png);
802     }
803     else
804     {
805         data = close_png;
806         len = WXSIZEOF(close_png);
807     }
808
809     // load it
810     wxMemoryInputStream mis(data, len);
811     wxImage image(mis, wxBITMAP_TYPE_PNG);
812     wxBitmap bmp(image);
813     wxASSERT_MSG( bmp.IsOk(), "failed to load embedded PNG image?" );
814
815     // and draw it centering it in the provided rectangle: we don't scale the
816     // image because this is really not going to look good for such a small
817     // (14*14) bitmap
818     dc.DrawBitmap(bmp, wxRect(bmp.GetSize()).CenterIn(rect).GetPosition());
819 }
820
821 #endif // wxHAS_DRAW_TITLE_BAR_BITMAP
822
823 #endif