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/mac/uma.h"
32 class WXDLLEXPORT wxRendererMac
: public wxDelegateRendererNative
35 // draw the header control button (used by wxListCtrl)
36 virtual void DrawHeaderButton( wxWindow
*win
,
40 wxHeaderSortIconType sortArrow
= wxHDR_SORT_ICON_NONE
,
41 wxHeaderButtonParams
* params
= NULL
);
43 virtual int GetHeaderButtonHeight(wxWindow
*win
);
45 // draw the expanded/collapsed icon for a tree control item
46 virtual void DrawTreeItemButton( wxWindow
*win
,
51 // draw a (vertical) sash
52 virtual void DrawSplitterSash( wxWindow
*win
,
61 wxBitmap m_bmpTreeExpanded
;
62 wxBitmap m_bmpTreeCollapsed
;
65 // ----------------------------------------------------------------------------
67 // ----------------------------------------------------------------------------
70 static const char *aqua_arrow_right_xpm
[] =
72 // columns rows colors chars-per-pixel
94 static const char *aqua_arrow_down_xpm
[] =
96 // columns rows colors chars-per-pixel
117 // ============================================================================
119 // ============================================================================
122 wxRendererNative
& wxRendererNative::GetDefault()
124 static wxRendererMac s_rendererMac
;
126 return s_rendererMac
;
129 void wxRendererMac::DrawHeaderButton( wxWindow
*win
,
133 wxHeaderSortIconType sortArrow
,
134 wxHeaderButtonParams
* params
)
136 const wxCoord x
= dc
.LogicalToDeviceX(rect
.x
/*- 1*/);
137 const wxCoord y
= dc
.LogicalToDeviceY(rect
.y
/*- 1*/);
138 const wxCoord w
= dc
.LogicalToDeviceXRel(rect
.width
);
139 const wxCoord h
= dc
.LogicalToDeviceYRel(rect
.height
);
141 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
143 HIRect headerRect
= CGRectMake( x
, y
, w
, h
);
144 if ( !dc
.IsKindOf( CLASSINFO( wxPaintDC
) ) )
148 (short) headerRect
.origin
.y
, (short) headerRect
.origin
.x
,
149 (short) (headerRect
.origin
.y
+ headerRect
.size
.height
),
150 (short) (headerRect
.origin
.x
+ headerRect
.size
.width
)
153 RgnHandle updateRgn
= NewRgn();
154 RectRgn( updateRgn
, &r
);
155 HIViewSetNeedsDisplayInRegion( (HIViewRef
) win
->GetHandle(), updateRgn
, true );
156 DisposeRgn( updateRgn
);
160 CGContextRef cgContext
;
162 #if wxMAC_USE_CORE_GRAPHICS
163 cgContext
= (CGContextRef
) dc
.GetGraphicsContext()->GetNativeContext();
167 GetPortBounds( (CGrafPtr
) dc
.m_macPort
, &bounds
);
168 QDBeginCGContext( (CGrafPtr
) dc
.m_macPort
, &cgContext
);
170 CGContextTranslateCTM( cgContext
, 0, bounds
.bottom
- bounds
.top
);
171 CGContextScaleCTM( cgContext
, 1, -1 );
173 HIShapeReplacePathInCGContext( HIShapeCreateWithQDRgn( (RgnHandle
) dc
.m_macCurrentClipRgn
), cgContext
);
174 CGContextClip( cgContext
);
175 HIViewConvertRect( &headerRect
, (HIViewRef
) win
->GetHandle(), (HIViewRef
) win
->MacGetTopLevelWindow()->GetHandle() );
179 HIThemeButtonDrawInfo drawInfo
;
182 memset( &drawInfo
, 0, sizeof(drawInfo
) );
183 drawInfo
.version
= 0;
184 drawInfo
.kind
= kThemeListHeaderButton
;
185 drawInfo
.state
= (flags
& wxCONTROL_DISABLED
) ? kThemeStateInactive
: kThemeStateActive
;
186 drawInfo
.value
= (flags
& wxCONTROL_SELECTED
) ? kThemeButtonOn
: kThemeButtonOff
;
187 drawInfo
.adornment
= kThemeAdornmentNone
;
189 // The down arrow is drawn automatically, change it to an up arrow if needed.
190 if ( sortArrow
== wxHDR_SORT_ICON_UP
)
191 drawInfo
.adornment
= kThemeAdornmentHeaderButtonSortUp
;
193 HIThemeDrawButton( &headerRect
, &drawInfo
, cgContext
, kHIThemeOrientationNormal
, &labelRect
);
195 // If we don't want any arrows we need to draw over the one already there
196 if ( (flags
& wxCONTROL_SELECTED
) && (sortArrow
== wxHDR_SORT_ICON_NONE
) )
198 // clip to the header rectangle
199 CGContextSaveGState( cgContext
);
200 CGContextClipToRect( cgContext
, headerRect
);
201 // but draw bigger than that so the arrow will get clipped off
202 headerRect
.size
.width
+= 25;
203 HIThemeDrawButton( &headerRect
, &drawInfo
, cgContext
, kHIThemeOrientationNormal
, &labelRect
);
204 CGContextRestoreGState( cgContext
);
208 #if wxMAC_USE_CORE_GRAPHICS
210 QDEndCGContext( (CGrafPtr
) dc
.m_macPort
, &cgContext
);
214 // Reserve room for the arrows before writing the label, and turn off the
215 // flags we've already handled
216 wxRect
newRect(rect
);
217 if ( (flags
& wxCONTROL_SELECTED
) && (sortArrow
!= wxHDR_SORT_ICON_NONE
) )
220 sortArrow
= wxHDR_SORT_ICON_NONE
;
222 flags
&= ~wxCONTROL_SELECTED
;
224 DrawHeaderButtonContents(win
, dc
, newRect
, flags
, sortArrow
, params
);
228 int wxRendererMac::GetHeaderButtonHeight(wxWindow
* WXUNUSED(win
))
230 SInt32 standardHeight
;
233 errStatus
= GetThemeMetric( kThemeMetricListHeaderHeight
, &standardHeight
);
234 if (errStatus
== noErr
)
236 return standardHeight
;
242 void wxRendererMac::DrawTreeItemButton( wxWindow
*win
,
247 // init the buttons on demand
248 if ( !m_bmpTreeExpanded
.Ok() )
250 m_bmpTreeExpanded
= wxBitmap(aqua_arrow_down_xpm
);
251 m_bmpTreeCollapsed
= wxBitmap(aqua_arrow_right_xpm
);
256 // VZ: this is the old code from treectlg.cpp which apparently doesn't work
257 // but I kept it here just in case it is needed -- if not, please
260 #if 0 // def __WXMAC__
261 wxMacPortSetter
helper(&dc
);
262 wxMacWindowClipper
clipper(this);
263 wxDC::MacSetupBackgroundForCurrentPort( MacGetBackgroundBrush() );
266 int loc_y
= y_mid
- 6;
267 MacWindowToRootWindow( &loc_x
, &loc_y
);
268 Rect bounds
= { loc_y
, loc_x
, loc_y
+ 18, loc_x
+ 12 };
269 ThemeButtonDrawInfo info
=
272 item
->IsExpanded() ? kThemeDisclosureDown
: kThemeDisclosureRight
,
276 DrawThemeButton( &bounds
, kThemeDisclosureButton
, &info
, NULL
, NULL
, NULL
, NULL
);
279 flags
& wxCONTROL_EXPANDED
281 : m_bmpTreeCollapsed
,
282 rect
.x
, rect
.y
, true /* use mask */);
286 void wxRendererMac::DrawSplitterSash( wxWindow
*win
,
290 wxOrientation orient
,
291 int WXUNUSED(flags
) )
293 bool hasMetal
= win
->MacGetTopLevelWindow()->MacGetMetalAppearance();
295 GetThemeMetric( kThemeMetricSmallPaneSplitterHeight
, &height
);
297 if (orient
== wxVERTICAL
)
298 splitterRect
= CGRectMake( position
, 0, height
, size
.y
);
300 splitterRect
= CGRectMake( 0, position
, size
.x
, height
);
302 #if !wxMAC_USE_CORE_GRAPHICS
305 (HIViewRef
) win
->GetHandle(),
306 (HIViewRef
) win
->MacGetTopLevelWindow()->GetHandle() );
309 // under compositing we should only draw when called by the OS, otherwise just issue a redraw command
310 // strange redraw errors occur if we don't do this
312 if ( !dc
.IsKindOf( CLASSINFO( wxPaintDC
) ) )
316 (short) splitterRect
.origin
.y
,
317 (short) splitterRect
.origin
.x
,
318 (short) (splitterRect
.origin
.y
+ splitterRect
.size
.height
),
319 (short) (splitterRect
.origin
.x
+ splitterRect
.size
.width
)
322 RgnHandle updateRgn
= NewRgn();
323 RectRgn( updateRgn
, &r
);
324 HIViewSetNeedsDisplayInRegion( (HIViewRef
) win
->GetHandle(), updateRgn
, true );
325 DisposeRgn( updateRgn
);
329 CGContextRef cgContext
;
331 #if wxMAC_USE_CORE_GRAPHICS
332 cgContext
= (CGContextRef
) dc
.GetGraphicsContext()->GetNativeContext();
335 GetPortBounds( (CGrafPtr
) dc
.m_macPort
, &bounds
);
336 QDBeginCGContext( (CGrafPtr
) dc
.m_macPort
, &cgContext
);
337 CGContextTranslateCTM( cgContext
, 0, bounds
.bottom
- bounds
.top
);
338 CGContextScaleCTM( cgContext
, 1, -1 );
341 HIThemeSplitterDrawInfo drawInfo
;
342 drawInfo
.version
= 0;
343 drawInfo
.state
= kThemeStateActive
;
344 drawInfo
.adornment
= hasMetal
? kHIThemeSplitterAdornmentMetal
: kHIThemeSplitterAdornmentNone
;
345 HIThemeDrawPaneSplitter( &splitterRect
, &drawInfo
, cgContext
, kHIThemeOrientationNormal
);
347 #if wxMAC_USE_CORE_GRAPHICS
349 QDEndCGContext( (CGrafPtr
) dc
.m_macPort
, &cgContext
);