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"
26 #include "wx/renderer.h"
27 #include "wx/toplevel.h"
28 #include "wx/dcclient.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 );