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
= dc
.XLOG2DEV(rect
.x
-1),
139 y
= dc
.YLOG2DEV(rect
.y
-1),
140 w
= dc
.XLOG2DEVREL(rect
.width
),
141 h
= dc
.YLOG2DEVREL(rect
.height
);
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 HIShapeReplacePathInCGContext( HIShapeCreateWithQDRgn( (RgnHandle
) dc
.m_macCurrentClipRgn
) , cgContext
) ;
173 CGContextClip( cgContext
) ;
174 HIViewConvertRect( &headerRect
, (HIViewRef
) win
->GetHandle() , (HIViewRef
) win
->MacGetTopLevelWindow()->GetHandle() ) ;
177 HIThemeButtonDrawInfo drawInfo
;
179 memset( &drawInfo
, 0 , sizeof(drawInfo
) ) ;
180 drawInfo
.version
= 0 ;
181 drawInfo
.state
= ( flags
& wxCONTROL_DISABLED
) ? kThemeStateInactive
: kThemeStateActive
;
182 drawInfo
.kind
= kThemeListHeaderButton
;
184 drawInfo
.adornment
= kThemeAdornmentNone
;
185 HIThemeDrawButton( &headerRect
, &drawInfo
, cgContext
, kHIThemeOrientationNormal
, &labelRect
) ;
187 #if wxMAC_USE_CORE_GRAPHICS
189 QDEndCGContext( (CGrafPtr
) dc
.m_macPort
, &cgContext
) ;
196 wxMacWindowClipper
clipper(win
) ;
197 Rect rect
= { y
, x
, y
+ h
, x
+ w
} ;
198 wxPoint origin
= win
->GetClientAreaOrigin() ;
202 win
->MacWindowToRootWindow( &dx
, &dy
) ;
203 OffsetRect( &rect
, dx
, dy
) ;
205 ThemeButtonDrawInfo drawInfo
;
206 memset( &drawInfo
, 0 , sizeof(drawInfo
) ) ;
207 drawInfo
.state
= ( flags
& wxCONTROL_DISABLED
) ? kThemeStateInactive
: kThemeStateActive
;
209 drawInfo
.adornment
= kThemeAdornmentNone
;
210 DrawThemeButton( &rect
, kThemeListHeaderButton
, &drawInfo
, NULL
, NULL
, NULL
, 0 ) ;
215 wxRendererMac::DrawTreeItemButton(wxWindow
*win
,
220 // init the buttons on demand
221 if ( !m_bmpTreeExpanded
.Ok() )
223 m_bmpTreeExpanded
= wxBitmap(aqua_arrow_down_xpm
);
224 m_bmpTreeCollapsed
= wxBitmap(aqua_arrow_right_xpm
);
229 // VZ: this is the old code from treectlg.cpp which apparently doesn't work
230 // but I kept it here just in case it is needed -- if not, please
232 #if 0 // def __WXMAC__
233 wxMacPortSetter
helper(&dc
) ;
234 wxMacWindowClipper
clipper(this) ;
235 wxDC::MacSetupBackgroundForCurrentPort( MacGetBackgroundBrush() ) ;
238 int loc_y
= y_mid
- 6 ;
239 MacWindowToRootWindow( & loc_x
, & loc_y
) ;
240 Rect bounds
= { loc_y
, loc_x
, loc_y
+ 18 , loc_x
+ 12 } ;
241 ThemeButtonDrawInfo info
= { kThemeStateActive
, item
->IsExpanded() ? kThemeDisclosureDown
: kThemeDisclosureRight
,
242 kThemeAdornmentNone
};
243 DrawThemeButton( &bounds
, kThemeDisclosureButton
,
244 &info
, NULL
, NULL
, NULL
, NULL
) ;
246 dc
.DrawBitmap(flags
& wxCONTROL_EXPANDED
? m_bmpTreeExpanded
247 : m_bmpTreeCollapsed
,
248 rect
.x
, rect
.y
, true /* use mask */);
253 wxRendererMac::DrawSplitterSash(wxWindow
*win
,
257 wxOrientation orient
,
260 #if defined(__WXMAC_OSX__) && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 )
261 if ( HIThemeDrawPaneSplitter
!= 0 )
263 bool hasMetal
= win
->MacGetTopLevelWindow()->MacGetMetalAppearance() ;
265 GetThemeMetric( kThemeMetricSmallPaneSplitterHeight
, &height
) ;
266 HIRect splitterRect
;
267 if ( orient
== wxVERTICAL
)
268 splitterRect
= CGRectMake( position
, 0 , height
, size
.y
);
270 splitterRect
= CGRectMake( 0 , position
, size
.x
, height
);
271 #if !wxMAC_USE_CORE_GRAPHICS
272 HIViewConvertRect( &splitterRect
, (HIViewRef
) win
->GetHandle() , (HIViewRef
) win
->MacGetTopLevelWindow()->GetHandle() ) ;
275 // under compositing we should only draw when called by the OS, otherwise just issue a redraw command
276 // strange redraw errors occur if we don't do this
278 if ( dc
.IsKindOf( CLASSINFO( wxPaintDC
) ) == false )
280 Rect r
= { (short) splitterRect
.origin
.y
, (short) splitterRect
.origin
.x
,
281 (short) (splitterRect
.origin
.y
+ splitterRect
.size
.height
) , (short) (splitterRect
.origin
.x
+ splitterRect
.size
.width
) } ;
282 RgnHandle updateRgn
= NewRgn() ;
283 RectRgn( updateRgn
, &r
) ;
284 HIViewSetNeedsDisplayInRegion( (HIViewRef
) win
->GetHandle() , updateRgn
, true ) ;
285 DisposeRgn( updateRgn
) ;
289 CGContextRef cgContext
;
290 #if wxMAC_USE_CORE_GRAPHICS
291 cgContext
= ((wxMacCGContext
*)(dc
.GetGraphicContext()))->GetNativeContext() ;
294 GetPortBounds( (CGrafPtr
) dc
.m_macPort
, &bounds
) ;
295 QDBeginCGContext( (CGrafPtr
) dc
.m_macPort
, &cgContext
) ;
296 CGContextTranslateCTM( cgContext
, 0 , bounds
.bottom
- bounds
.top
) ;
297 CGContextScaleCTM( cgContext
, 1 , -1 ) ;
300 HIThemeSplitterDrawInfo drawInfo
;
301 drawInfo
.version
= 0 ;
302 drawInfo
.state
= kThemeStateActive
;
303 drawInfo
.adornment
= hasMetal
? kHIThemeSplitterAdornmentMetal
: kHIThemeSplitterAdornmentNone
;
304 HIThemeDrawPaneSplitter( &splitterRect
, &drawInfo
, cgContext
, kHIThemeOrientationNormal
) ;
306 #if wxMAC_USE_CORE_GRAPHICS
308 QDEndCGContext( (CGrafPtr
) dc
.m_macPort
, &cgContext
) ;
315 // Do the gradient fill:
316 static int grayValues
[] =
318 0xA0, 0xF6, 0xED, 0xE4, 0xE2, 0xD0, 0xA0
320 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
321 if ( orient
== wxVERTICAL
)
324 for (i
=0; i
< (int)WXSIZEOF(grayValues
); i
++)
326 dc
.SetPen( wxPen( wxColour( grayValues
[i
] , grayValues
[i
] , grayValues
[i
] ),
328 dc
.DrawRectangle( position
+i
, 0, 1, size
.y
);
334 for (i
=0; i
< (int)WXSIZEOF(grayValues
); i
++)
336 dc
.SetPen( wxPen( wxColour( grayValues
[i
] , grayValues
[i
] , grayValues
[i
] ),
338 dc
.DrawRectangle( 0, position
+i
, size
.x
, 1 );