]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/carbon/renderer.cpp
Merge new item attributes if any are already existing
[wxWidgets.git] / src / mac / carbon / renderer.cpp
... / ...
CommitLineData
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/mac/carbon/renderer.cpp
3// Purpose: implementation of wxRendererNative for Mac
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>
9// License: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
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"
21 #include "wx/dc.h"
22 #include "wx/bitmap.h"
23 #include "wx/settings.h"
24 #include "wx/dcclient.h"
25 #include "wx/toplevel.h"
26#endif
27
28#include "wx/renderer.h"
29#include "wx/mac/uma.h"
30
31
32class WXDLLEXPORT wxRendererMac : public wxDelegateRendererNative
33{
34public:
35 // draw the header control button (used by wxListCtrl)
36 virtual void DrawHeaderButton( wxWindow *win,
37 wxDC& dc,
38 const wxRect& rect,
39 int flags = 0,
40 wxHeaderSortIconType sortArrow = wxHDR_SORT_ICON_NONE,
41 wxHeaderButtonParams* params = NULL );
42
43 virtual int GetHeaderButtonHeight(wxWindow *win);
44
45 // draw the expanded/collapsed icon for a tree control item
46 virtual void DrawTreeItemButton( wxWindow *win,
47 wxDC& dc,
48 const wxRect& rect,
49 int flags = 0 );
50
51 // draw a (vertical) sash
52 virtual void DrawSplitterSash( wxWindow *win,
53 wxDC& dc,
54 const wxSize& size,
55 wxCoord position,
56 wxOrientation orient,
57 int flags = 0 );
58
59private:
60 // the tree buttons
61 wxBitmap m_bmpTreeExpanded;
62 wxBitmap m_bmpTreeCollapsed;
63};
64
65// ----------------------------------------------------------------------------
66// Aqua arrows
67// ----------------------------------------------------------------------------
68
69/* XPM */
70static const char *aqua_arrow_right_xpm[] =
71{
72// columns rows colors chars-per-pixel
73"13 11 4 1",
74" c None",
75"b c #C0C0C0",
76"c c #707070",
77"d c #A0A0A0",
78
79// pixels
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 */
94static const char *aqua_arrow_down_xpm[] =
95{
96// columns rows colors chars-per-pixel
97"13 11 4 1",
98" c None",
99"b c #C0C0C0",
100"c c #707070",
101"d c #A0A0A0",
102
103// pixels
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
121// static
122wxRendererNative& wxRendererNative::GetDefault()
123{
124 static wxRendererMac s_rendererMac;
125
126 return s_rendererMac;
127}
128
129void wxRendererMac::DrawHeaderButton( wxWindow *win,
130 wxDC& dc,
131 const wxRect& rect,
132 int flags,
133 wxHeaderSortIconType sortArrow,
134 wxHeaderButtonParams* params )
135{
136 const wxCoord x = dc.XLOG2DEV(rect.x /*- 1*/);
137 const wxCoord y = dc.YLOG2DEV(rect.y /*- 1*/);
138 const wxCoord w = dc.XLOG2DEVREL(rect.width);
139 const wxCoord h = dc.YLOG2DEVREL(rect.height);
140
141 dc.SetBrush( *wxTRANSPARENT_BRUSH );
142
143 HIRect headerRect = CGRectMake( x, y, w, h );
144 if ( !dc.IsKindOf( CLASSINFO( wxPaintDC ) ) )
145 {
146 Rect r =
147 {
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;
161
162#if wxMAC_USE_CORE_GRAPHICS
163 cgContext = ((wxMacCGContext*)(dc.GetGraphicContext()))->GetNativeContext();
164#else
165 Rect bounds;
166
167 GetPortBounds( (CGrafPtr) dc.m_macPort, &bounds );
168 QDBeginCGContext( (CGrafPtr) dc.m_macPort, &cgContext );
169
170 CGContextTranslateCTM( cgContext, 0, bounds.bottom - bounds.top );
171 CGContextScaleCTM( cgContext, 1, -1 );
172
173 HIShapeReplacePathInCGContext( HIShapeCreateWithQDRgn( (RgnHandle) dc.m_macCurrentClipRgn ), cgContext );
174 CGContextClip( cgContext );
175 HIViewConvertRect( &headerRect, (HIViewRef) win->GetHandle(), (HIViewRef) win->MacGetTopLevelWindow()->GetHandle() );
176#endif
177
178 {
179 HIThemeButtonDrawInfo drawInfo;
180 HIRect labelRect;
181
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;
188
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;
192
193 HIThemeDrawButton( &headerRect, &drawInfo, cgContext, kHIThemeOrientationNormal, &labelRect );
194
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) )
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 }
206 }
207
208#if wxMAC_USE_CORE_GRAPHICS
209#else
210 QDEndCGContext( (CGrafPtr) dc.m_macPort, &cgContext );
211#endif
212 }
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);
217 if ( (flags & wxCONTROL_SELECTED) && (sortArrow != wxHDR_SORT_ICON_NONE) )
218 {
219 newRect.width -= 12;
220 sortArrow = wxHDR_SORT_ICON_NONE;
221 }
222 flags &= ~wxCONTROL_SELECTED;
223
224 DrawHeaderButtonContents(win, dc, newRect, flags, sortArrow, params);
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;
239}
240
241
242void wxRendererMac::DrawTreeItemButton( wxWindow *win,
243 wxDC& dc,
244 const wxRect& rect,
245 int flags )
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
259
260#if 0 // def __WXMAC__
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 );
277#else // 1
278 dc.DrawBitmap(
279 flags & wxCONTROL_EXPANDED
280 ? m_bmpTreeExpanded
281 : m_bmpTreeCollapsed,
282 rect.x, rect.y, true /* use mask */);
283#endif
284}
285
286void wxRendererMac::DrawSplitterSash( wxWindow *win,
287 wxDC& dc,
288 const wxSize& size,
289 wxCoord position,
290 wxOrientation orient,
291 int WXUNUSED(flags) )
292{
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 );
301
302#if !wxMAC_USE_CORE_GRAPHICS
303 HIViewConvertRect(
304 &splitterRect,
305 (HIViewRef) win->GetHandle(),
306 (HIViewRef) win->MacGetTopLevelWindow()->GetHandle() );
307#endif
308
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
311
312 if ( !dc.IsKindOf( CLASSINFO( wxPaintDC ) ) )
313 {
314 Rect r =
315 {
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;
330
331#if wxMAC_USE_CORE_GRAPHICS
332 cgContext = ((wxMacCGContext*)(dc.GetGraphicContext()))->GetNativeContext();
333#else
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 );
339#endif
340
341 HIThemeSplitterDrawInfo drawInfo;
342 drawInfo.version = 0;
343 drawInfo.state = kThemeStateActive;
344 drawInfo.adornment = hasMetal ? kHIThemeSplitterAdornmentMetal : kHIThemeSplitterAdornmentNone;
345 HIThemeDrawPaneSplitter( &splitterRect, &drawInfo, cgContext, kHIThemeOrientationNormal );
346
347#if wxMAC_USE_CORE_GRAPHICS
348#else
349 QDEndCGContext( (CGrafPtr) dc.m_macPort, &cgContext );
350#endif
351 }
352}