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