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