1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        mac/renderer.cpp 
   3 // Purpose:     implementation of wxRendererNative for Mac 
   4 // Author:      Vadim Zeitlin 
   8 // Copyright:   (c) 2003 Vadim Zeitlin <vadim@wxwindows.org> 
   9 // License:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 // for compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  28     #include "wx/string.h" 
  30     #include "wx/bitmap.h" 
  31     #include "wx/settings.h" 
  34 #include "wx/renderer.h" 
  35 #include "wx/toplevel.h" 
  36 #include "wx/dcclient.h" 
  37 #include "wx/mac/uma.h" 
  39 // ---------------------------------------------------------------------------- 
  40 // wxRendererMac: our wxRendererNative implementation 
  41 // ---------------------------------------------------------------------------- 
  43 class WXDLLEXPORT wxRendererMac 
: public wxDelegateRendererNative
 
  46     // draw the header control button (used by wxListCtrl) 
  47     virtual void DrawHeaderButton(wxWindow 
*win
, 
  52     // draw the expanded/collapsed icon for a tree control item 
  53     virtual void DrawTreeItemButton(wxWindow 
*win
, 
  58     // draw a (vertical) sash 
  59     virtual void DrawSplitterSash(wxWindow 
*win
, 
  68     wxBitmap m_bmpTreeExpanded
, 
  72 // ---------------------------------------------------------------------------- 
  74 // ---------------------------------------------------------------------------- 
  77 static const char *aqua_arrow_right_xpm
[] = { 
  78 /* columns rows colors chars-per-pixel */ 
  99 static const char *aqua_arrow_down_xpm
[] = { 
 100 /* columns rows colors chars-per-pixel */ 
 120 // ============================================================================ 
 122 // ============================================================================ 
 125 wxRendererNative
& wxRendererNative::GetDefault() 
 127     static wxRendererMac s_rendererMac
; 
 129     return s_rendererMac
; 
 133 wxRendererMac::DrawHeaderButton(wxWindow 
*win
, 
 138     const wxCoord x 
= rect
.x
-1, 
 144     wxGetOsVersion( &major
, &minor 
); 
 146     dc
.SetBrush( *wxTRANSPARENT_BRUSH 
); 
 148 #if defined(__WXMAC_OSX__) && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 ) 
 149     if ( HIThemeDrawButton 
!= 0 ) 
 151         HIRect headerRect 
= CGRectMake( x 
, y 
, w 
, h 
); 
 152         if ( dc
.IsKindOf( CLASSINFO( wxPaintDC 
) ) == false ) 
 154             Rect r 
= { (short) headerRect
.origin
.y 
, (short) headerRect
.origin
.x 
,  
 155                 (short) (headerRect
.origin
.y 
+ headerRect
.size
.height
) , (short) (headerRect
.origin
.x 
+ headerRect
.size
.width
) } ; 
 156             RgnHandle updateRgn 
= NewRgn() ; 
 157             RectRgn( updateRgn 
, &r 
) ; 
 158             HIViewSetNeedsDisplayInRegion( (HIViewRef
) win
->GetHandle() , updateRgn 
, true ) ; 
 159             DisposeRgn( updateRgn 
) ; 
 163             CGContextRef cgContext 
; 
 164 #if wxMAC_USE_CORE_GRAPHICS 
 165             cgContext 
= ((wxMacCGContext
*)(dc
.GetGraphicContext()))->GetNativeContext() ; 
 168             GetPortBounds( (CGrafPtr
) dc
.m_macPort 
, &bounds 
) ; 
 169             QDBeginCGContext( (CGrafPtr
) dc
.m_macPort 
, &cgContext 
) ; 
 170             CGContextTranslateCTM( cgContext 
, 0 , bounds
.bottom 
- bounds
.top 
) ; 
 171             CGContextScaleCTM( cgContext 
, 1 , -1 ) ; 
 172             HIViewConvertRect( &headerRect 
, (HIViewRef
) win
->GetHandle() , (HIViewRef
) win
->MacGetTopLevelWindow()->GetHandle() ) ; 
 175                 HIThemeButtonDrawInfo drawInfo 
; 
 177                 memset( &drawInfo 
, 0 , sizeof(drawInfo
) ) ; 
 178                 drawInfo
.version 
= 0 ; 
 179                 drawInfo
.state 
= ( flags 
& wxCONTROL_DISABLED 
) ? kThemeStateInactive 
: kThemeStateActive 
; 
 180                 drawInfo
.kind 
= kThemeListHeaderButton 
; 
 182                 drawInfo
.adornment 
= kThemeAdornmentNone 
; 
 183                 HIThemeDrawButton( &headerRect 
, &drawInfo 
, cgContext 
, kHIThemeOrientationNormal 
, &labelRect 
) ;     
 185 #if wxMAC_USE_CORE_GRAPHICS 
 187             QDEndCGContext( (CGrafPtr
) dc
.m_macPort 
, &cgContext 
) ; 
 194         wxMacWindowClipper 
clipper(win
) ; 
 195         Rect rect 
= { y 
, x 
, y 
+ h 
, x 
+ w 
} ; 
 196         wxPoint origin 
= win
->GetClientAreaOrigin() ; 
 200         win
->MacWindowToRootWindow( &dx 
, &dy 
) ; 
 201         OffsetRect( &rect 
, dx 
, dy 
) ; 
 203         ThemeButtonDrawInfo drawInfo 
; 
 204         memset( &drawInfo 
, 0 , sizeof(drawInfo
) ) ; 
 205         drawInfo
.state 
= ( flags 
& wxCONTROL_DISABLED 
) ? kThemeStateInactive 
: kThemeStateActive 
;  
 207         drawInfo
.adornment 
= kThemeAdornmentNone 
; 
 208         DrawThemeButton( &rect 
, kThemeListHeaderButton 
, &drawInfo 
, NULL 
, NULL 
, NULL 
, 0 ) ; 
 213 wxRendererMac::DrawTreeItemButton(wxWindow 
*win
, 
 218     // init the buttons on demand 
 219     if ( !m_bmpTreeExpanded
.Ok() ) 
 221         m_bmpTreeExpanded 
= wxBitmap(aqua_arrow_down_xpm
); 
 222         m_bmpTreeCollapsed 
= wxBitmap(aqua_arrow_right_xpm
); 
 227     // VZ: this is the old code from treectlg.cpp which apparently doesn't work 
 228     //     but I kept it here just in case it is needed -- if not, please 
 230 #if 0 // def __WXMAC__ 
 231     wxMacPortSetter 
helper(&dc
) ; 
 232     wxMacWindowClipper 
clipper(this) ; 
 233     wxDC::MacSetupBackgroundForCurrentPort( MacGetBackgroundBrush() ) ; 
 236     int loc_y 
= y_mid 
- 6 ; 
 237     MacWindowToRootWindow( & loc_x 
, & loc_y 
) ; 
 238     Rect bounds 
= { loc_y 
, loc_x 
, loc_y 
+ 18 , loc_x 
+ 12 } ; 
 239     ThemeButtonDrawInfo info 
= { kThemeStateActive 
, item
->IsExpanded() ? kThemeDisclosureDown 
: kThemeDisclosureRight 
, 
 240         kThemeAdornmentNone 
};  
 241     DrawThemeButton( &bounds
, kThemeDisclosureButton 
,  
 242         &info 
, NULL 
, NULL 
, NULL 
, NULL 
) ; 
 244     dc
.DrawBitmap(flags 
& wxCONTROL_EXPANDED 
? m_bmpTreeExpanded
 
 245                                              : m_bmpTreeCollapsed
, 
 246                   rect
.x
, rect
.y
, true /* use mask */); 
 251 wxRendererMac::DrawSplitterSash(wxWindow 
*win
, 
 255                                 wxOrientation orient
, 
 258 #if defined(__WXMAC_OSX__) && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 ) 
 259     if ( HIThemeDrawPaneSplitter 
!= 0 ) 
 261         bool hasMetal 
= win
->MacGetTopLevelWindow()->MacGetMetalAppearance() ; 
 263         GetThemeMetric( kThemeMetricSmallPaneSplitterHeight 
, &height 
) ; 
 264         HIRect splitterRect 
; 
 265         if ( orient 
== wxVERTICAL 
) 
 266             splitterRect 
= CGRectMake( position 
, 0 , height
, size
.y
); 
 268             splitterRect 
= CGRectMake( 0 , position 
, size
.x 
, height 
); 
 269 #if !wxMAC_USE_CORE_GRAPHICS 
 270         HIViewConvertRect( &splitterRect 
, (HIViewRef
) win
->GetHandle() , (HIViewRef
) win
->MacGetTopLevelWindow()->GetHandle() ) ; 
 273         // under compositing we should only draw when called by the OS, otherwise just issue a redraw command 
 274         // strange redraw errors occur if we don't do this 
 276         if ( dc
.IsKindOf( CLASSINFO( wxPaintDC 
) ) == false ) 
 278             Rect r 
= { (short) splitterRect
.origin
.y 
, (short) splitterRect
.origin
.x 
,  
 279                 (short) (splitterRect
.origin
.y 
+ splitterRect
.size
.height
) , (short) (splitterRect
.origin
.x 
+ splitterRect
.size
.width
) } ; 
 280             RgnHandle updateRgn 
= NewRgn() ; 
 281             RectRgn( updateRgn 
, &r 
) ; 
 282             HIViewSetNeedsDisplayInRegion( (HIViewRef
) win
->GetHandle() , updateRgn 
, true ) ; 
 283             DisposeRgn( updateRgn 
) ; 
 287             CGContextRef cgContext 
; 
 288 #if wxMAC_USE_CORE_GRAPHICS 
 289             cgContext 
= ((wxMacCGContext
*)(dc
.GetGraphicContext()))->GetNativeContext() ; 
 292             GetPortBounds( (CGrafPtr
) dc
.m_macPort 
, &bounds 
) ; 
 293             QDBeginCGContext( (CGrafPtr
) dc
.m_macPort 
, &cgContext 
) ; 
 294             CGContextTranslateCTM( cgContext 
, 0 , bounds
.bottom 
- bounds
.top 
) ; 
 295             CGContextScaleCTM( cgContext 
, 1 , -1 ) ; 
 298             HIThemeSplitterDrawInfo drawInfo 
; 
 299             drawInfo
.version 
= 0 ; 
 300             drawInfo
.state 
= kThemeStateActive 
; 
 301             drawInfo
.adornment 
= hasMetal 
? kHIThemeSplitterAdornmentMetal 
: kHIThemeSplitterAdornmentNone 
; 
 302             HIThemeDrawPaneSplitter( &splitterRect 
, &drawInfo 
, cgContext 
, kHIThemeOrientationNormal 
) ;     
 304 #if wxMAC_USE_CORE_GRAPHICS 
 306             QDEndCGContext( (CGrafPtr
) dc
.m_macPort 
, &cgContext 
) ; 
 313         // Do the gradient fill: 
 314         static int grayValues
[] =  
 316             0xA0, 0xF6, 0xED, 0xE4, 0xE2, 0xD0, 0xA0 
 318         dc
.SetBrush( *wxTRANSPARENT_BRUSH 
); 
 319         if ( orient 
== wxVERTICAL 
) 
 322             for (i
=0; i 
< (int)WXSIZEOF(grayValues
); i
++)  
 324                 dc
.SetPen( wxPen( wxColour( grayValues
[i
] , grayValues
[i
] , grayValues
[i
] ), 
 326                 dc
.DrawRectangle( position
+i
, 0, 1, size
.y 
); 
 332             for (i
=0; i 
< (int)WXSIZEOF(grayValues
); i
++)  
 334                 dc
.SetPen( wxPen( wxColour( grayValues
[i
] , grayValues
[i
] , grayValues
[i
] ), 
 336                 dc
.DrawRectangle( 0, position
+i
, size
.x
, 1 );