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