]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/renderer.cpp
Implemented Mac-style button toggling within wxButtonToolBar, and line
[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"
7af14d71 24#endif
9c7f49f5
VZ
25
26#include "wx/renderer.h"
5d91a088
GD
27#include "wx/toplevel.h"
28#include "wx/dcclient.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,
39 int flags = 0 );
9c7f49f5
VZ
40
41 // draw the expanded/collapsed icon for a tree control item
7af14d71
DS
42 virtual void DrawTreeItemButton( wxWindow *win,
43 wxDC& dc,
44 const wxRect& rect,
45 int flags = 0 );
9c7f49f5 46
b3208e11 47 // draw a (vertical) sash
7af14d71
DS
48 virtual void DrawSplitterSash( wxWindow *win,
49 wxDC& dc,
50 const wxSize& size,
51 wxCoord position,
52 wxOrientation orient,
53 int flags = 0 );
b3208e11 54
9c7f49f5
VZ
55private:
56 // the tree buttons
7af14d71
DS
57 wxBitmap m_bmpTreeExpanded;
58 wxBitmap m_bmpTreeCollapsed;
9c7f49f5
VZ
59};
60
61// ----------------------------------------------------------------------------
62// Aqua arrows
63// ----------------------------------------------------------------------------
64
65/* XPM */
7af14d71
DS
66static const char *aqua_arrow_right_xpm[] =
67{
68// columns rows colors chars-per-pixel
9c7f49f5
VZ
69"13 11 4 1",
70" c None",
71"b c #C0C0C0",
72"c c #707070",
73"d c #A0A0A0",
7af14d71
DS
74
75// pixels
9c7f49f5
VZ
76" b ",
77" ddb ",
78" cccdb ",
79" cccccd ",
80" ccccccdb ",
81" ccccccccd",
82" ccccccdb ",
83" cccccb ",
84" cccdb ",
85" ddb ",
86" b "
87};
88
89/* XPM */
7af14d71
DS
90static const char *aqua_arrow_down_xpm[] =
91{
92// columns rows colors chars-per-pixel
9c7f49f5
VZ
93"13 11 4 1",
94" c None",
95"b c #C0C0C0",
96"c c #707070",
97"d c #A0A0A0",
7af14d71
DS
98
99// pixels
9c7f49f5
VZ
100" ",
101" ",
102" bdcccccccdb ",
103" dcccccccd ",
104" bcccccccb ",
105" dcccccd ",
106" bcccccb ",
107" bcccd ",
108" dcd ",
109" bcb ",
110" d "
111};
112
113// ============================================================================
114// implementation
115// ============================================================================
116
7af14d71 117// static
f0244295 118wxRendererNative& wxRendererNative::GetDefault()
9c7f49f5
VZ
119{
120 static wxRendererMac s_rendererMac;
121
122 return s_rendererMac;
123}
124
7af14d71
DS
125void wxRendererMac::DrawHeaderButton( wxWindow *win,
126 wxDC& dc,
127 const wxRect& rect,
128 int flags )
9c7f49f5 129{
7af14d71 130 int major, minor;
9c7f49f5 131
11d1adbf 132 wxGetOsVersion( &major, &minor );
9c7f49f5 133
7af14d71
DS
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);
138
11d1adbf 139 dc.SetBrush( *wxTRANSPARENT_BRUSH );
9c7f49f5 140
2480cf88
SC
141#if defined(__WXMAC_OSX__) && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 )
142 if ( HIThemeDrawButton != 0 )
143 {
7af14d71
DS
144 HIRect headerRect = CGRectMake( x, y, w, h );
145 if ( !dc.IsKindOf( CLASSINFO( wxPaintDC ) ) )
2480cf88 146 {
7af14d71
DS
147 Rect r =
148 {
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 );
2480cf88
SC
158 }
159 else
160 {
7af14d71
DS
161 CGContextRef cgContext;
162
2480cf88 163#if wxMAC_USE_CORE_GRAPHICS
7af14d71 164 cgContext = ((wxMacCGContext*)(dc.GetGraphicContext()))->GetNativeContext();
2480cf88 165#else
7af14d71
DS
166 Rect bounds;
167
168 GetPortBounds( (CGrafPtr) dc.m_macPort, &bounds );
169 QDBeginCGContext( (CGrafPtr) dc.m_macPort, &cgContext );
170
171 CGContextTranslateCTM( cgContext, 0, bounds.bottom - bounds.top );
172 CGContextScaleCTM( cgContext, 1, -1 );
173
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
2480cf88 179 {
7af14d71
DS
180 HIThemeButtonDrawInfo drawInfo;
181 HIRect labelRect;
182
183 memset( &drawInfo, 0, sizeof(drawInfo) );
184 drawInfo.version = 0;
185 drawInfo.state = (flags & wxCONTROL_DISABLED) ? kThemeStateInactive : kThemeStateActive;
186 drawInfo.kind = kThemeListHeaderButton;
187 drawInfo.value = 0;
188 drawInfo.adornment = kThemeAdornmentNone;
189 HIThemeDrawButton( &headerRect, &drawInfo, cgContext, kHIThemeOrientationNormal, &labelRect );
2480cf88 190 }
7af14d71 191
2480cf88
SC
192#if wxMAC_USE_CORE_GRAPHICS
193#else
7af14d71 194 QDEndCGContext( (CGrafPtr) dc.m_macPort, &cgContext );
2480cf88
SC
195#endif
196 }
197 }
198 else
199#endif
11d1adbf 200 {
7af14d71
DS
201 wxMacWindowClipper clipper(win);
202 Rect rect = { y, x, y + h, x + w };
203 wxPoint origin = win->GetClientAreaOrigin();
204 int dx, dy;
205 dx = origin.x;
206 dy = origin.y;
207 win->MacWindowToRootWindow( &dx, &dy );
208 OffsetRect( &rect, dx, dy );
209
210 ThemeButtonDrawInfo drawInfo;
211 memset( &drawInfo, 0, sizeof(drawInfo) );
212 drawInfo.state = (flags & wxCONTROL_DISABLED) ? kThemeStateInactive : kThemeStateActive;
213 drawInfo.value = 0;
214 drawInfo.adornment = kThemeAdornmentNone;
215 DrawThemeButton( &rect, kThemeListHeaderButton, &drawInfo, NULL, NULL, NULL, 0 );
11d1adbf 216 }
9c7f49f5
VZ
217}
218
7af14d71
DS
219void wxRendererMac::DrawTreeItemButton( wxWindow *win,
220 wxDC& dc,
221 const wxRect& rect,
222 int flags )
9c7f49f5
VZ
223{
224 // init the buttons on demand
225 if ( !m_bmpTreeExpanded.Ok() )
226 {
227 m_bmpTreeExpanded = wxBitmap(aqua_arrow_down_xpm);
228 m_bmpTreeCollapsed = wxBitmap(aqua_arrow_right_xpm);
229 }
230
231 // draw them
232
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
235 // remove it
7af14d71 236
9c7f49f5 237#if 0 // def __WXMAC__
7af14d71
DS
238 wxMacPortSetter helper(&dc);
239 wxMacWindowClipper clipper(this);
240 wxDC::MacSetupBackgroundForCurrentPort( MacGetBackgroundBrush() );
241
242 int loc_x = x - 5;
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 =
247 {
248 kThemeStateActive,
249 item->IsExpanded() ? kThemeDisclosureDown : kThemeDisclosureRight,
250 kThemeAdornmentNone
251 };
252
253 DrawThemeButton( &bounds, kThemeDisclosureButton, &info, NULL, NULL, NULL, NULL );
9c7f49f5 254#else // 1
7af14d71
DS
255 dc.DrawBitmap(
256 flags & wxCONTROL_EXPANDED
257 ? m_bmpTreeExpanded
258 : m_bmpTreeCollapsed,
259 rect.x, rect.y, true /* use mask */);
260#endif
9c7f49f5
VZ
261}
262
7af14d71
DS
263void wxRendererMac::DrawSplitterSash( wxWindow *win,
264 wxDC& dc,
265 const wxSize& size,
266 wxCoord position,
267 wxOrientation orient,
268 int WXUNUSED(flags) )
b3208e11 269{
2480cf88
SC
270#if defined(__WXMAC_OSX__) && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 )
271 if ( HIThemeDrawPaneSplitter != 0 )
eef4e26c 272 {
7af14d71
DS
273 bool hasMetal = win->MacGetTopLevelWindow()->MacGetMetalAppearance();
274 SInt32 height;
275 GetThemeMetric( kThemeMetricSmallPaneSplitterHeight, &height );
276 HIRect splitterRect;
277 if (orient == wxVERTICAL)
278 splitterRect = CGRectMake( position, 0, height, size.y );
547aafd2 279 else
7af14d71
DS
280 splitterRect = CGRectMake( 0, position, size.x, height );
281
2480cf88 282#if !wxMAC_USE_CORE_GRAPHICS
7af14d71
DS
283 HIViewConvertRect(
284 &splitterRect,
285 (HIViewRef) win->GetHandle(),
286 (HIViewRef) win->MacGetTopLevelWindow()->GetHandle() );
2480cf88 287#endif
547aafd2
SC
288
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
291
7af14d71 292 if ( !dc.IsKindOf( CLASSINFO( wxPaintDC ) ) )
eef4e26c 293 {
7af14d71
DS
294 Rect r =
295 {
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)
300 };
301
302 RgnHandle updateRgn = NewRgn();
303 RectRgn( updateRgn, &r );
304 HIViewSetNeedsDisplayInRegion( (HIViewRef) win->GetHandle(), updateRgn, true );
305 DisposeRgn( updateRgn );
547aafd2
SC
306 }
307 else
308 {
7af14d71
DS
309 CGContextRef cgContext;
310
20b69855 311#if wxMAC_USE_CORE_GRAPHICS
7af14d71 312 cgContext = ((wxMacCGContext*)(dc.GetGraphicContext()))->GetNativeContext();
20b69855 313#else
7af14d71
DS
314 Rect bounds;
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 );
2480cf88 319#endif
547aafd2 320
7af14d71
DS
321 HIThemeSplitterDrawInfo drawInfo;
322 drawInfo.version = 0;
323 drawInfo.state = kThemeStateActive;
324 drawInfo.adornment = hasMetal ? kHIThemeSplitterAdornmentMetal : kHIThemeSplitterAdornmentNone;
325 HIThemeDrawPaneSplitter( &splitterRect, &drawInfo, cgContext, kHIThemeOrientationNormal );
2480cf88
SC
326
327#if wxMAC_USE_CORE_GRAPHICS
328#else
7af14d71 329 QDEndCGContext( (CGrafPtr) dc.m_macPort, &cgContext );
20b69855 330#endif
eef4e26c
RR
331 }
332 }
333 else
547aafd2 334#endif
eef4e26c 335 {
547aafd2 336 // Do the gradient fill:
7af14d71 337 static int grayValues[] =
eef4e26c 338 {
547aafd2
SC
339 0xA0, 0xF6, 0xED, 0xE4, 0xE2, 0xD0, 0xA0
340 };
7af14d71
DS
341 int i;
342
547aafd2 343 dc.SetBrush( *wxTRANSPARENT_BRUSH );
7af14d71 344 if (orient == wxVERTICAL)
547aafd2 345 {
7af14d71 346 for (i=0; i < (int)WXSIZEOF(grayValues); i++)
547aafd2 347 {
7af14d71
DS
348 dc.SetPen( wxPen( wxColour( grayValues[i], grayValues[i], grayValues[i] ), 1, wxSOLID ) );
349 dc.DrawRectangle( position + i, 0, 1, size.y );
547aafd2
SC
350 }
351 }
352 else
353 {
7af14d71 354 for (i=0; i < (int)WXSIZEOF(grayValues); i++)
547aafd2 355 {
7af14d71
DS
356 dc.SetPen( wxPen( wxColour( grayValues[i], grayValues[i], grayValues[i] ), 1, wxSOLID ) );
357 dc.DrawRectangle( 0, position + i, size.x, 1 );
547aafd2 358 }
eef4e26c 359 }
547aafd2 360 }
b3208e11
VZ
361}
362