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"
25 #include "wx/toplevel.h"
28 #include "wx/renderer.h"
29 #include "wx/graphics.h"
30 #include "wx/mac/uma.h"
33 class WXDLLEXPORT wxRendererMac
: public wxDelegateRendererNative
36 // draw the header control button (used by wxListCtrl)
37 virtual void DrawHeaderButton( wxWindow
*win
,
41 wxHeaderSortIconType sortArrow
= wxHDR_SORT_ICON_NONE
,
42 wxHeaderButtonParams
* params
= NULL
);
44 virtual int GetHeaderButtonHeight(wxWindow
*win
);
46 // draw the expanded/collapsed icon for a tree control item
47 virtual void DrawTreeItemButton( wxWindow
*win
,
52 // draw a (vertical) sash
53 virtual void DrawSplitterSash( wxWindow
*win
,
62 wxBitmap m_bmpTreeExpanded
;
63 wxBitmap m_bmpTreeCollapsed
;
66 // ----------------------------------------------------------------------------
68 // ----------------------------------------------------------------------------
71 static const char *aqua_arrow_right_xpm
[] =
73 // columns rows colors chars-per-pixel
95 static const char *aqua_arrow_down_xpm
[] =
97 // columns rows colors chars-per-pixel
118 // ============================================================================
120 // ============================================================================
123 wxRendererNative
& wxRendererNative::GetDefault()
125 static wxRendererMac s_rendererMac
;
127 return s_rendererMac
;
130 void wxRendererMac::DrawHeaderButton( wxWindow
*win
,
134 wxHeaderSortIconType sortArrow
,
135 wxHeaderButtonParams
* params
)
137 const wxCoord x
= dc
.LogicalToDeviceX(rect
.x
/*- 1*/);
138 const wxCoord y
= dc
.LogicalToDeviceY(rect
.y
/*- 1*/);
139 const wxCoord w
= dc
.LogicalToDeviceXRel(rect
.width
);
140 const wxCoord h
= dc
.LogicalToDeviceYRel(rect
.height
);
142 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
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
= (CGContextRef
) dc
.GetGraphicsContext()->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
.kind
= kThemeListHeaderButton
;
186 drawInfo
.state
= (flags
& wxCONTROL_DISABLED
) ? kThemeStateInactive
: kThemeStateActive
;
187 drawInfo
.value
= (flags
& wxCONTROL_SELECTED
) ? kThemeButtonOn
: kThemeButtonOff
;
188 drawInfo
.adornment
= kThemeAdornmentNone
;
190 // The down arrow is drawn automatically, change it to an up arrow if needed.
191 if ( sortArrow
== wxHDR_SORT_ICON_UP
)
192 drawInfo
.adornment
= kThemeAdornmentHeaderButtonSortUp
;
194 HIThemeDrawButton( &headerRect
, &drawInfo
, cgContext
, kHIThemeOrientationNormal
, &labelRect
);
196 // If we don't want any arrows we need to draw over the one already there
197 if ( (flags
& wxCONTROL_SELECTED
) && (sortArrow
== wxHDR_SORT_ICON_NONE
) )
199 // clip to the header rectangle
200 CGContextSaveGState( cgContext
);
201 CGContextClipToRect( cgContext
, headerRect
);
202 // but draw bigger than that so the arrow will get clipped off
203 headerRect
.size
.width
+= 25;
204 HIThemeDrawButton( &headerRect
, &drawInfo
, cgContext
, kHIThemeOrientationNormal
, &labelRect
);
205 CGContextRestoreGState( cgContext
);
209 #if wxMAC_USE_CORE_GRAPHICS
211 QDEndCGContext( (CGrafPtr
) dc
.m_macPort
, &cgContext
);
215 // Reserve room for the arrows before writing the label, and turn off the
216 // flags we've already handled
217 wxRect
newRect(rect
);
218 if ( (flags
& wxCONTROL_SELECTED
) && (sortArrow
!= wxHDR_SORT_ICON_NONE
) )
221 sortArrow
= wxHDR_SORT_ICON_NONE
;
223 flags
&= ~wxCONTROL_SELECTED
;
225 DrawHeaderButtonContents(win
, dc
, newRect
, flags
, sortArrow
, params
);
229 int wxRendererMac::GetHeaderButtonHeight(wxWindow
* WXUNUSED(win
))
231 SInt32 standardHeight
;
234 errStatus
= GetThemeMetric( kThemeMetricListHeaderHeight
, &standardHeight
);
235 if (errStatus
== noErr
)
237 return standardHeight
;
243 void wxRendererMac::DrawTreeItemButton( wxWindow
*win
,
248 // init the buttons on demand
249 if ( !m_bmpTreeExpanded
.Ok() )
251 m_bmpTreeExpanded
= wxBitmap(aqua_arrow_down_xpm
);
252 m_bmpTreeCollapsed
= wxBitmap(aqua_arrow_right_xpm
);
257 // VZ: this is the old code from treectlg.cpp which apparently doesn't work
258 // but I kept it here just in case it is needed -- if not, please
261 #if 0 // def __WXMAC__
262 wxMacPortSetter
helper(&dc
);
263 wxMacWindowClipper
clipper(this);
264 wxDC::MacSetupBackgroundForCurrentPort( MacGetBackgroundBrush() );
267 int loc_y
= y_mid
- 6;
268 MacWindowToRootWindow( &loc_x
, &loc_y
);
269 Rect bounds
= { loc_y
, loc_x
, loc_y
+ 18, loc_x
+ 12 };
270 ThemeButtonDrawInfo info
=
273 item
->IsExpanded() ? kThemeDisclosureDown
: kThemeDisclosureRight
,
277 DrawThemeButton( &bounds
, kThemeDisclosureButton
, &info
, NULL
, NULL
, NULL
, NULL
);
280 flags
& wxCONTROL_EXPANDED
282 : m_bmpTreeCollapsed
,
283 rect
.x
, rect
.y
, true /* use mask */);
287 void wxRendererMac::DrawSplitterSash( wxWindow
*win
,
291 wxOrientation orient
,
292 int WXUNUSED(flags
) )
294 bool hasMetal
= win
->MacGetTopLevelWindow()->MacGetMetalAppearance();
296 GetThemeMetric( kThemeMetricSmallPaneSplitterHeight
, &height
);
298 if (orient
== wxVERTICAL
)
299 splitterRect
= CGRectMake( position
, 0, height
, size
.y
);
301 splitterRect
= CGRectMake( 0, position
, size
.x
, height
);
303 #if !wxMAC_USE_CORE_GRAPHICS
306 (HIViewRef
) win
->GetHandle(),
307 (HIViewRef
) win
->MacGetTopLevelWindow()->GetHandle() );
310 // under compositing we should only draw when called by the OS, otherwise just issue a redraw command
311 // strange redraw errors occur if we don't do this
313 if ( !dc
.IsKindOf( CLASSINFO( wxPaintDC
) ) )
317 (short) splitterRect
.origin
.y
,
318 (short) splitterRect
.origin
.x
,
319 (short) (splitterRect
.origin
.y
+ splitterRect
.size
.height
),
320 (short) (splitterRect
.origin
.x
+ splitterRect
.size
.width
)
323 RgnHandle updateRgn
= NewRgn();
324 RectRgn( updateRgn
, &r
);
325 HIViewSetNeedsDisplayInRegion( (HIViewRef
) win
->GetHandle(), updateRgn
, true );
326 DisposeRgn( updateRgn
);
330 CGContextRef cgContext
;
332 #if wxMAC_USE_CORE_GRAPHICS
333 cgContext
= (CGContextRef
) dc
.GetGraphicsContext()->GetNativeContext();
336 GetPortBounds( (CGrafPtr
) dc
.m_macPort
, &bounds
);
337 QDBeginCGContext( (CGrafPtr
) dc
.m_macPort
, &cgContext
);
338 CGContextTranslateCTM( cgContext
, 0, bounds
.bottom
- bounds
.top
);
339 CGContextScaleCTM( cgContext
, 1, -1 );
342 HIThemeSplitterDrawInfo drawInfo
;
343 drawInfo
.version
= 0;
344 drawInfo
.state
= kThemeStateActive
;
345 drawInfo
.adornment
= hasMetal
? kHIThemeSplitterAdornmentMetal
: kHIThemeSplitterAdornmentNone
;
346 HIThemeDrawPaneSplitter( &splitterRect
, &drawInfo
, cgContext
, kHIThemeOrientationNormal
);
348 #if wxMAC_USE_CORE_GRAPHICS
350 QDEndCGContext( (CGrafPtr
) dc
.m_macPort
, &cgContext
);