1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/mac/carbon/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 // for compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  20     #include "wx/string.h" 
  22     #include "wx/bitmap.h" 
  23     #include "wx/settings.h" 
  24     #include "wx/dcclient.h" 
  27 #include "wx/renderer.h" 
  28 #include "wx/toplevel.h" 
  29 #include "wx/mac/uma.h" 
  32 class WXDLLEXPORT wxRendererMac 
: public wxDelegateRendererNative
 
  35     // draw the header control button (used by wxListCtrl) 
  36     virtual void DrawHeaderButton( wxWindow 
*win
, 
  41     // draw the expanded/collapsed icon for a tree control item 
  42     virtual void DrawTreeItemButton( wxWindow 
*win
, 
  47     // draw a (vertical) sash 
  48     virtual void DrawSplitterSash( wxWindow 
*win
, 
  57     wxBitmap m_bmpTreeExpanded
; 
  58     wxBitmap m_bmpTreeCollapsed
; 
  61 // ---------------------------------------------------------------------------- 
  63 // ---------------------------------------------------------------------------- 
  66 static const char *aqua_arrow_right_xpm
[] = 
  68 // columns rows colors chars-per-pixel 
  90 static const char *aqua_arrow_down_xpm
[] = 
  92 // columns rows colors chars-per-pixel 
 113 // ============================================================================ 
 115 // ============================================================================ 
 118 wxRendererNative
& wxRendererNative::GetDefault() 
 120     static wxRendererMac s_rendererMac
; 
 122     return s_rendererMac
; 
 125 void wxRendererMac::DrawHeaderButton( wxWindow 
*win
, 
 132     wxGetOsVersion( &major
, &minor 
); 
 134     const wxCoord x 
= dc
.XLOG2DEV(rect
.x 
- 1); 
 135     const wxCoord y 
= dc
.YLOG2DEV(rect
.y 
- 1); 
 136     const wxCoord w 
= dc
.XLOG2DEVREL(rect
.width
); 
 137     const wxCoord h 
= dc
.YLOG2DEVREL(rect
.height
); 
 139     dc
.SetBrush( *wxTRANSPARENT_BRUSH 
); 
 141 #if defined(__WXMAC_OSX__) && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 ) 
 142     if ( HIThemeDrawButton 
!= 0 ) 
 144         HIRect headerRect 
= CGRectMake( x
, y
, w
, h 
); 
 145         if ( !dc
.IsKindOf( CLASSINFO( wxPaintDC 
) ) ) 
 149                 (short) headerRect
.origin
.y
, (short) headerRect
.origin
.x
, 
 150                 (short) (headerRect
.origin
.y 
+ headerRect
.size
.height
), 
 151                 (short) (headerRect
.origin
.x 
+ headerRect
.size
.width
) 
 154             RgnHandle updateRgn 
= NewRgn(); 
 155             RectRgn( updateRgn
, &r 
); 
 156             HIViewSetNeedsDisplayInRegion( (HIViewRef
) win
->GetHandle(), updateRgn
, true ); 
 157             DisposeRgn( updateRgn 
); 
 161             CGContextRef cgContext
; 
 163 #if wxMAC_USE_CORE_GRAPHICS 
 164             cgContext 
= ((wxMacCGContext
*)(dc
.GetGraphicContext()))->GetNativeContext(); 
 168             GetPortBounds( (CGrafPtr
) dc
.m_macPort
, &bounds 
); 
 169             QDBeginCGContext( (CGrafPtr
) dc
.m_macPort
, &cgContext 
); 
 171             CGContextTranslateCTM( cgContext
, 0, bounds
.bottom 
- bounds
.top 
); 
 172             CGContextScaleCTM( cgContext
, 1, -1 ); 
 174             HIShapeReplacePathInCGContext( HIShapeCreateWithQDRgn( (RgnHandle
) dc
.m_macCurrentClipRgn 
), cgContext 
); 
 175             CGContextClip( cgContext 
); 
 176             HIViewConvertRect( &headerRect
, (HIViewRef
) win
->GetHandle(), (HIViewRef
) win
->MacGetTopLevelWindow()->GetHandle() ); 
 180                 HIThemeButtonDrawInfo drawInfo
; 
 183                 memset( &drawInfo
, 0, sizeof(drawInfo
) ); 
 184                 drawInfo
.version 
= 0; 
 185                 drawInfo
.state 
= (flags 
& wxCONTROL_DISABLED
) ? kThemeStateInactive 
: kThemeStateActive
; 
 186                 drawInfo
.kind 
= kThemeListHeaderButton
; 
 188                 drawInfo
.adornment 
= kThemeAdornmentNone
; 
 189                 HIThemeDrawButton( &headerRect
, &drawInfo
, cgContext
, kHIThemeOrientationNormal
, &labelRect 
); 
 192 #if wxMAC_USE_CORE_GRAPHICS 
 194             QDEndCGContext( (CGrafPtr
) dc
.m_macPort
, &cgContext 
); 
 201         wxMacWindowClipper 
clipper(win
); 
 202         Rect rect 
= { y
, x
, y 
+ h
, x 
+ w 
}; 
 203         wxPoint origin 
= win
->GetClientAreaOrigin(); 
 207         win
->MacWindowToRootWindow( &dx
, &dy 
); 
 208         OffsetRect( &rect
, dx
, dy 
); 
 210         ThemeButtonDrawInfo drawInfo
; 
 211         memset( &drawInfo
, 0, sizeof(drawInfo
) ); 
 212         drawInfo
.state 
= (flags 
& wxCONTROL_DISABLED
) ? kThemeStateInactive 
: kThemeStateActive
; 
 214         drawInfo
.adornment 
= kThemeAdornmentNone
; 
 215         DrawThemeButton( &rect
, kThemeListHeaderButton
, &drawInfo
, NULL
, NULL
, NULL
, 0 ); 
 219 void wxRendererMac::DrawTreeItemButton( wxWindow 
*win
, 
 224     // init the buttons on demand 
 225     if ( !m_bmpTreeExpanded
.Ok() ) 
 227         m_bmpTreeExpanded 
= wxBitmap(aqua_arrow_down_xpm
); 
 228         m_bmpTreeCollapsed 
= wxBitmap(aqua_arrow_right_xpm
); 
 233     // VZ: this is the old code from treectlg.cpp which apparently doesn't work 
 234     //     but I kept it here just in case it is needed -- if not, please 
 237 #if 0 // def __WXMAC__ 
 238     wxMacPortSetter 
helper(&dc
); 
 239     wxMacWindowClipper 
clipper(this); 
 240     wxDC::MacSetupBackgroundForCurrentPort( MacGetBackgroundBrush() ); 
 243     int loc_y 
= y_mid 
- 6; 
 244     MacWindowToRootWindow( &loc_x
, &loc_y 
); 
 245     Rect bounds 
= { loc_y
, loc_x
, loc_y 
+ 18, loc_x 
+ 12 }; 
 246     ThemeButtonDrawInfo info 
= 
 249         item
->IsExpanded() ? kThemeDisclosureDown 
: kThemeDisclosureRight
, 
 253     DrawThemeButton( &bounds
, kThemeDisclosureButton
, &info
, NULL
, NULL
, NULL
, NULL 
); 
 256         flags 
& wxCONTROL_EXPANDED
 
 258         : m_bmpTreeCollapsed
, 
 259          rect
.x
, rect
.y
, true /* use mask */); 
 263 void wxRendererMac::DrawSplitterSash( wxWindow 
*win
, 
 267     wxOrientation orient
, 
 268     int WXUNUSED(flags
) ) 
 270 #if defined(__WXMAC_OSX__) && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 ) 
 271     if ( HIThemeDrawPaneSplitter 
!= 0 ) 
 273         bool hasMetal 
= win
->MacGetTopLevelWindow()->MacGetMetalAppearance(); 
 275         GetThemeMetric( kThemeMetricSmallPaneSplitterHeight
, &height 
); 
 277         if (orient 
== wxVERTICAL
) 
 278             splitterRect 
= CGRectMake( position
, 0, height
, size
.y 
); 
 280             splitterRect 
= CGRectMake( 0, position
, size
.x
, height 
); 
 282 #if !wxMAC_USE_CORE_GRAPHICS 
 285             (HIViewRef
) win
->GetHandle(), 
 286             (HIViewRef
) win
->MacGetTopLevelWindow()->GetHandle() ); 
 289         // under compositing we should only draw when called by the OS, otherwise just issue a redraw command 
 290         // strange redraw errors occur if we don't do this 
 292         if ( !dc
.IsKindOf( CLASSINFO( wxPaintDC 
) ) ) 
 296                 (short) splitterRect
.origin
.y
, 
 297                 (short) splitterRect
.origin
.x
, 
 298                 (short) (splitterRect
.origin
.y 
+ splitterRect
.size
.height
), 
 299                 (short) (splitterRect
.origin
.x 
+ splitterRect
.size
.width
) 
 302             RgnHandle updateRgn 
= NewRgn(); 
 303             RectRgn( updateRgn
, &r 
); 
 304             HIViewSetNeedsDisplayInRegion( (HIViewRef
) win
->GetHandle(), updateRgn
, true ); 
 305             DisposeRgn( updateRgn 
); 
 309             CGContextRef cgContext
; 
 311 #if wxMAC_USE_CORE_GRAPHICS 
 312             cgContext 
= ((wxMacCGContext
*)(dc
.GetGraphicContext()))->GetNativeContext(); 
 315             GetPortBounds( (CGrafPtr
) dc
.m_macPort
, &bounds 
); 
 316             QDBeginCGContext( (CGrafPtr
) dc
.m_macPort
, &cgContext 
); 
 317             CGContextTranslateCTM( cgContext
, 0, bounds
.bottom 
- bounds
.top 
); 
 318             CGContextScaleCTM( cgContext
, 1, -1 ); 
 321             HIThemeSplitterDrawInfo drawInfo
; 
 322             drawInfo
.version 
= 0; 
 323             drawInfo
.state 
= kThemeStateActive
; 
 324             drawInfo
.adornment 
= hasMetal 
? kHIThemeSplitterAdornmentMetal 
: kHIThemeSplitterAdornmentNone
; 
 325             HIThemeDrawPaneSplitter( &splitterRect
, &drawInfo
, cgContext
, kHIThemeOrientationNormal 
); 
 327 #if wxMAC_USE_CORE_GRAPHICS 
 329             QDEndCGContext( (CGrafPtr
) dc
.m_macPort
, &cgContext 
); 
 336         // Do the gradient fill: 
 337         static int grayValues
[] = 
 339             0xA0, 0xF6, 0xED, 0xE4, 0xE2, 0xD0, 0xA0 
 343         dc
.SetBrush( *wxTRANSPARENT_BRUSH 
); 
 344         if (orient 
== wxVERTICAL
) 
 346             for (i
=0; i 
< (int)WXSIZEOF(grayValues
); i
++) 
 348                 dc
.SetPen( wxPen( wxColour( grayValues
[i
], grayValues
[i
], grayValues
[i
] ), 1, wxSOLID 
) ); 
 349                 dc
.DrawRectangle( position 
+ i
, 0, 1, size
.y 
); 
 354             for (i
=0; i 
< (int)WXSIZEOF(grayValues
); i
++) 
 356                 dc
.SetPen( wxPen( wxColour( grayValues
[i
], grayValues
[i
], grayValues
[i
] ), 1, wxSOLID 
) ); 
 357                 dc
.DrawRectangle( 0, position 
+ i
, size
.x
, 1 );