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