]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/renderer.cpp
on demand creation of native CGContexts , so that pure text measuring contexts don...
[wxWidgets.git] / src / mac / carbon / renderer.cpp
CommitLineData
9c7f49f5 1///////////////////////////////////////////////////////////////////////////////
7af14d71 2// Name: src/mac/carbon/renderer.cpp
38c4cb6a 3// Purpose: implementation of wxRendererNative for Mac
9c7f49f5
VZ
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 20.07.2003
7// RCS-ID: $Id$
8// Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
65571936 9// License: wxWindows licence
9c7f49f5
VZ
10///////////////////////////////////////////////////////////////////////////////
11
9c7f49f5
VZ
12// for compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
16 #pragma hdrstop
17#endif
18
19#ifndef WX_PRECOMP
20 #include "wx/string.h"
4c948343
VZ
21 #include "wx/dc.h"
22 #include "wx/bitmap.h"
23 #include "wx/settings.h"
ed4b0fdc 24 #include "wx/dcclient.h"
1832043f 25 #include "wx/toplevel.h"
7af14d71 26#endif
9c7f49f5
VZ
27
28#include "wx/renderer.h"
8acd14d1 29#include "wx/graphics.h"
547aafd2 30#include "wx/mac/uma.h"
9c7f49f5 31
9c7f49f5 32
5cb80ad2 33class WXDLLEXPORT wxRendererMac : public wxDelegateRendererNative
9c7f49f5
VZ
34{
35public:
36 // draw the header control button (used by wxListCtrl)
7af14d71
DS
37 virtual void DrawHeaderButton( wxWindow *win,
38 wxDC& dc,
39 const wxRect& rect,
4b94ddc4 40 int flags = 0,
80752b57 41 wxHeaderSortIconType sortArrow = wxHDR_SORT_ICON_NONE,
4b94ddc4 42 wxHeaderButtonParams* params = NULL );
9c7f49f5 43
4b94ddc4
RD
44 virtual int GetHeaderButtonHeight(wxWindow *win);
45
9c7f49f5 46 // draw the expanded/collapsed icon for a tree control item
7af14d71
DS
47 virtual void DrawTreeItemButton( wxWindow *win,
48 wxDC& dc,
49 const wxRect& rect,
50 int flags = 0 );
9c7f49f5 51
b3208e11 52 // draw a (vertical) sash
7af14d71
DS
53 virtual void DrawSplitterSash( wxWindow *win,
54 wxDC& dc,
55 const wxSize& size,
56 wxCoord position,
57 wxOrientation orient,
58 int flags = 0 );
b3208e11 59
9c7f49f5
VZ
60private:
61 // the tree buttons
7af14d71
DS
62 wxBitmap m_bmpTreeExpanded;
63 wxBitmap m_bmpTreeCollapsed;
9c7f49f5
VZ
64};
65
66// ----------------------------------------------------------------------------
67// Aqua arrows
68// ----------------------------------------------------------------------------
69
70/* XPM */
7af14d71
DS
71static const char *aqua_arrow_right_xpm[] =
72{
73// columns rows colors chars-per-pixel
9c7f49f5
VZ
74"13 11 4 1",
75" c None",
76"b c #C0C0C0",
77"c c #707070",
78"d c #A0A0A0",
7af14d71
DS
79
80// pixels
9c7f49f5
VZ
81" b ",
82" ddb ",
83" cccdb ",
84" cccccd ",
85" ccccccdb ",
86" ccccccccd",
87" ccccccdb ",
88" cccccb ",
89" cccdb ",
90" ddb ",
91" b "
92};
93
94/* XPM */
7af14d71
DS
95static const char *aqua_arrow_down_xpm[] =
96{
97// columns rows colors chars-per-pixel
9c7f49f5
VZ
98"13 11 4 1",
99" c None",
100"b c #C0C0C0",
101"c c #707070",
102"d c #A0A0A0",
7af14d71
DS
103
104// pixels
9c7f49f5
VZ
105" ",
106" ",
107" bdcccccccdb ",
108" dcccccccd ",
109" bcccccccb ",
110" dcccccd ",
111" bcccccb ",
112" bcccd ",
113" dcd ",
114" bcb ",
115" d "
116};
117
118// ============================================================================
119// implementation
120// ============================================================================
121
7af14d71 122// static
f0244295 123wxRendererNative& wxRendererNative::GetDefault()
9c7f49f5
VZ
124{
125 static wxRendererMac s_rendererMac;
126
127 return s_rendererMac;
128}
129
7af14d71
DS
130void wxRendererMac::DrawHeaderButton( wxWindow *win,
131 wxDC& dc,
132 const wxRect& rect,
4b94ddc4 133 int flags,
80752b57 134 wxHeaderSortIconType sortArrow,
4b94ddc4 135 wxHeaderButtonParams* params )
9c7f49f5 136{
977d15a6
SC
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);
7af14d71 141
11d1adbf 142 dc.SetBrush( *wxTRANSPARENT_BRUSH );
9c7f49f5 143
a62f32af
SC
144 HIRect headerRect = CGRectMake( x, y, w, h );
145 if ( !dc.IsKindOf( CLASSINFO( wxPaintDC ) ) )
2480cf88 146 {
a62f32af 147 Rect r =
2480cf88 148 {
a62f32af
SC
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)
152 };
153
154 RgnHandle updateRgn = NewRgn();
155 RectRgn( updateRgn, &r );
156 HIViewSetNeedsDisplayInRegion( (HIViewRef) win->GetHandle(), updateRgn, true );
157 DisposeRgn( updateRgn );
158 }
159 else
160 {
161 CGContextRef cgContext;
7af14d71 162
2480cf88 163#if wxMAC_USE_CORE_GRAPHICS
be01a403 164 cgContext = (CGContextRef) dc.GetGraphicsContext()->GetNativeContext();
2480cf88 165#else
a62f32af 166 Rect bounds;
7af14d71 167
a62f32af
SC
168 GetPortBounds( (CGrafPtr) dc.m_macPort, &bounds );
169 QDBeginCGContext( (CGrafPtr) dc.m_macPort, &cgContext );
7af14d71 170
a62f32af
SC
171 CGContextTranslateCTM( cgContext, 0, bounds.bottom - bounds.top );
172 CGContextScaleCTM( cgContext, 1, -1 );
7af14d71 173
a62f32af
SC
174 HIShapeReplacePathInCGContext( HIShapeCreateWithQDRgn( (RgnHandle) dc.m_macCurrentClipRgn ), cgContext );
175 CGContextClip( cgContext );
176 HIViewConvertRect( &headerRect, (HIViewRef) win->GetHandle(), (HIViewRef) win->MacGetTopLevelWindow()->GetHandle() );
2480cf88 177#endif
7af14d71 178
a62f32af
SC
179 {
180 HIThemeButtonDrawInfo drawInfo;
181 HIRect labelRect;
7af14d71 182
a62f32af
SC
183 memset( &drawInfo, 0, sizeof(drawInfo) );
184 drawInfo.version = 0;
a62f32af 185 drawInfo.kind = kThemeListHeaderButton;
4b94ddc4
RD
186 drawInfo.state = (flags & wxCONTROL_DISABLED) ? kThemeStateInactive : kThemeStateActive;
187 drawInfo.value = (flags & wxCONTROL_SELECTED) ? kThemeButtonOn : kThemeButtonOff;
a62f32af 188 drawInfo.adornment = kThemeAdornmentNone;
4b94ddc4
RD
189
190 // The down arrow is drawn automatically, change it to an up arrow if needed.
80752b57 191 if ( sortArrow == wxHDR_SORT_ICON_UP )
4b94ddc4
RD
192 drawInfo.adornment = kThemeAdornmentHeaderButtonSortUp;
193
a62f32af 194 HIThemeDrawButton( &headerRect, &drawInfo, cgContext, kHIThemeOrientationNormal, &labelRect );
4b94ddc4
RD
195
196 // If we don't want any arrows we need to draw over the one already there
80752b57 197 if ( (flags & wxCONTROL_SELECTED) && (sortArrow == wxHDR_SORT_ICON_NONE) )
4b94ddc4
RD
198 {
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 );
206 }
a62f32af 207 }
7af14d71 208
2480cf88
SC
209#if wxMAC_USE_CORE_GRAPHICS
210#else
a62f32af 211 QDEndCGContext( (CGrafPtr) dc.m_macPort, &cgContext );
2480cf88 212#endif
11d1adbf 213 }
4b94ddc4
RD
214
215 // Reserve room for the arrows before writing the label, and turn off the
216 // flags we've already handled
217 wxRect newRect(rect);
80752b57 218 if ( (flags & wxCONTROL_SELECTED) && (sortArrow != wxHDR_SORT_ICON_NONE) )
4b94ddc4
RD
219 {
220 newRect.width -= 12;
80752b57 221 sortArrow = wxHDR_SORT_ICON_NONE;
4b94ddc4 222 }
80752b57 223 flags &= ~wxCONTROL_SELECTED;
4b94ddc4 224
80752b57 225 DrawHeaderButtonContents(win, dc, newRect, flags, sortArrow, params);
4b94ddc4
RD
226}
227
228
229int wxRendererMac::GetHeaderButtonHeight(wxWindow* WXUNUSED(win))
230{
231 SInt32 standardHeight;
232 OSStatus errStatus;
233
234 errStatus = GetThemeMetric( kThemeMetricListHeaderHeight, &standardHeight );
235 if (errStatus == noErr)
236 {
237 return standardHeight;
238 }
239 return -1;
9c7f49f5
VZ
240}
241
4b94ddc4 242
7af14d71
DS
243void wxRendererMac::DrawTreeItemButton( wxWindow *win,
244 wxDC& dc,
245 const wxRect& rect,
246 int flags )
9c7f49f5
VZ
247{
248 // init the buttons on demand
249 if ( !m_bmpTreeExpanded.Ok() )
250 {
251 m_bmpTreeExpanded = wxBitmap(aqua_arrow_down_xpm);
252 m_bmpTreeCollapsed = wxBitmap(aqua_arrow_right_xpm);
253 }
254
255 // draw them
256
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
259 // remove it
7af14d71 260
9c7f49f5 261#if 0 // def __WXMAC__
7af14d71
DS
262 wxMacPortSetter helper(&dc);
263 wxMacWindowClipper clipper(this);
264 wxDC::MacSetupBackgroundForCurrentPort( MacGetBackgroundBrush() );
265
266 int loc_x = x - 5;
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 =
271 {
272 kThemeStateActive,
273 item->IsExpanded() ? kThemeDisclosureDown : kThemeDisclosureRight,
274 kThemeAdornmentNone
275 };
276
277 DrawThemeButton( &bounds, kThemeDisclosureButton, &info, NULL, NULL, NULL, NULL );
9c7f49f5 278#else // 1
7af14d71
DS
279 dc.DrawBitmap(
280 flags & wxCONTROL_EXPANDED
281 ? m_bmpTreeExpanded
282 : m_bmpTreeCollapsed,
283 rect.x, rect.y, true /* use mask */);
284#endif
9c7f49f5
VZ
285}
286
7af14d71
DS
287void wxRendererMac::DrawSplitterSash( wxWindow *win,
288 wxDC& dc,
289 const wxSize& size,
290 wxCoord position,
291 wxOrientation orient,
292 int WXUNUSED(flags) )
b3208e11 293{
a62f32af
SC
294 bool hasMetal = win->MacGetTopLevelWindow()->MacGetMetalAppearance();
295 SInt32 height;
296 GetThemeMetric( kThemeMetricSmallPaneSplitterHeight, &height );
297 HIRect splitterRect;
298 if (orient == wxVERTICAL)
299 splitterRect = CGRectMake( position, 0, height, size.y );
300 else
301 splitterRect = CGRectMake( 0, position, size.x, height );
7af14d71 302
2480cf88 303#if !wxMAC_USE_CORE_GRAPHICS
a62f32af
SC
304 HIViewConvertRect(
305 &splitterRect,
306 (HIViewRef) win->GetHandle(),
307 (HIViewRef) win->MacGetTopLevelWindow()->GetHandle() );
2480cf88 308#endif
547aafd2 309
a62f32af
SC
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
547aafd2 312
a62f32af
SC
313 if ( !dc.IsKindOf( CLASSINFO( wxPaintDC ) ) )
314 {
315 Rect r =
547aafd2 316 {
a62f32af
SC
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)
321 };
322
323 RgnHandle updateRgn = NewRgn();
324 RectRgn( updateRgn, &r );
325 HIViewSetNeedsDisplayInRegion( (HIViewRef) win->GetHandle(), updateRgn, true );
326 DisposeRgn( updateRgn );
327 }
328 else
329 {
330 CGContextRef cgContext;
7af14d71 331
20b69855 332#if wxMAC_USE_CORE_GRAPHICS
be01a403 333 cgContext = (CGContextRef) dc.GetGraphicsContext()->GetNativeContext();
20b69855 334#else
a62f32af
SC
335 Rect bounds;
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 );
2480cf88 340#endif
547aafd2 341
a62f32af
SC
342 HIThemeSplitterDrawInfo drawInfo;
343 drawInfo.version = 0;
344 drawInfo.state = kThemeStateActive;
345 drawInfo.adornment = hasMetal ? kHIThemeSplitterAdornmentMetal : kHIThemeSplitterAdornmentNone;
346 HIThemeDrawPaneSplitter( &splitterRect, &drawInfo, cgContext, kHIThemeOrientationNormal );
2480cf88
SC
347
348#if wxMAC_USE_CORE_GRAPHICS
349#else
a62f32af 350 QDEndCGContext( (CGrafPtr) dc.m_macPort, &cgContext );
20b69855 351#endif
547aafd2 352 }
b3208e11 353}