1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: mac/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 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // for compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
28 #include "wx/string.h"
30 #include "wx/bitmap.h"
31 #include "wx/settings.h"
34 #include "wx/renderer.h"
35 #include "wx/toplevel.h"
36 #include "wx/dcclient.h"
37 #include "wx/mac/uma.h"
39 // ----------------------------------------------------------------------------
40 // wxRendererMac: our wxRendererNative implementation
41 // ----------------------------------------------------------------------------
43 class WXDLLEXPORT wxRendererMac
: public wxDelegateRendererNative
46 // draw the header control button (used by wxListCtrl)
47 virtual void DrawHeaderButton(wxWindow
*win
,
52 // draw the expanded/collapsed icon for a tree control item
53 virtual void DrawTreeItemButton(wxWindow
*win
,
58 // draw a (vertical) sash
59 virtual void DrawSplitterSash(wxWindow
*win
,
68 wxBitmap m_bmpTreeExpanded
,
72 // ----------------------------------------------------------------------------
74 // ----------------------------------------------------------------------------
77 static const char *aqua_arrow_right_xpm
[] = {
78 /* columns rows colors chars-per-pixel */
99 static const char *aqua_arrow_down_xpm
[] = {
100 /* columns rows colors chars-per-pixel */
120 // ============================================================================
122 // ============================================================================
125 wxRendererNative
& wxRendererNative::GetDefault()
127 static wxRendererMac s_rendererMac
;
129 return s_rendererMac
;
133 wxRendererMac::DrawHeaderButton(wxWindow
*win
,
138 const int CORNER
= 1;
140 const wxCoord x
= rect
.x
-1,
146 wxGetOsVersion( &major
, &minor
);
148 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
152 dc
.SetPen( wxPen( wxColour( 0xC5 , 0xC5 , 0xC5 ) , 1 , wxSOLID
) );
153 dc
.DrawRectangle( x
, y
+CORNER
, 1, h
-CORNER
); // left
154 // The right border is overdrawn by the left border of the right neighbouring
155 // header (to maintain a proper single pixel border). Except for the
156 // rightmost header of the listctrl.
157 dc
.DrawRectangle( x
+w
+(CORNER
*2), y
+CORNER
, 1, h
-CORNER
); // right
158 dc
.SetPen( wxPen( wxColour( 0xB1 , 0xB1 , 0xB1 ) , 1 , wxSOLID
) );
159 dc
.DrawRectangle( x
, y
+h
, w
+(CORNER
*3), 1 ); // bottom
160 dc
.DrawRectangle( x
, y
, w
+(CORNER
*3), 1 ); // top
162 // Do a fill of the interior for background:
163 dc
.SetPen( wxPen( wxColour( 0xF6 , 0xF6 , 0xF6 ) , 1 , wxSOLID
) );
164 dc
.DrawRectangle( x
+CORNER
, y
+CORNER
, w
+CORNER
, h
-CORNER
);
166 // Do the gradient fill:
167 static int grayValues
[] =
169 0xF6, 0xF2, 0xEF, 0xED, 0xED, 0xEB, 0xEA, 0xEA, 0xE8,
170 0xE8, 0xE2, 0xE5, 0xE8, 0xEB, 0xEF, 0xF2, 0xFD
173 for (i
=0; i
< h
&& i
< (int)WXSIZEOF(grayValues
); i
++)
175 dc
.SetPen( wxPen( wxColour( grayValues
[i
] , grayValues
[i
] , grayValues
[i
] ),
177 dc
.DrawRectangle( x
+CORNER
, y
+CORNER
+i
, w
+CORNER
, 1 );
182 dc
.SetPen( wxPen( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNSHADOW
) , 1 , wxSOLID
) );
183 dc
.DrawLine( x
+w
-CORNER
+1, y
, x
+w
, y
+h
); // right (outer)
184 dc
.DrawRectangle( x
, y
+h
, w
+1, 1 ); // bottom (outer)
186 wxPen
pen( wxColour( 0x88 , 0x88 , 0x88 ), 1, wxSOLID
);
189 dc
.DrawLine( x
+w
-CORNER
, y
, x
+w
-1, y
+h
); // right (inner)
190 dc
.DrawRectangle( x
+1, y
+h
-1, w
-2, 1 ); // bottom (inner)
192 dc
.SetPen( *wxWHITE_PEN
);
193 dc
.DrawRectangle( x
, y
, w
-CORNER
+1, 1 ); // top (outer)
194 dc
.DrawRectangle( x
, y
, 1, h
); // left (outer)
195 dc
.DrawLine( x
, y
+h
-1, x
+1, y
+h
-1 );
196 dc
.DrawLine( x
+w
-1, y
, x
+w
-1, y
+1 );
201 wxRendererMac::DrawTreeItemButton(wxWindow
*win
,
206 // init the buttons on demand
207 if ( !m_bmpTreeExpanded
.Ok() )
209 m_bmpTreeExpanded
= wxBitmap(aqua_arrow_down_xpm
);
210 m_bmpTreeCollapsed
= wxBitmap(aqua_arrow_right_xpm
);
215 // VZ: this is the old code from treectlg.cpp which apparently doesn't work
216 // but I kept it here just in case it is needed -- if not, please
218 #if 0 // def __WXMAC__
219 wxMacPortSetter
helper(&dc
) ;
220 wxMacWindowClipper
clipper(this) ;
221 wxDC::MacSetupBackgroundForCurrentPort( MacGetBackgroundBrush() ) ;
224 int loc_y
= y_mid
- 6 ;
225 MacWindowToRootWindow( & loc_x
, & loc_y
) ;
226 Rect bounds
= { loc_y
, loc_x
, loc_y
+ 18 , loc_x
+ 12 } ;
227 ThemeButtonDrawInfo info
= { kThemeStateActive
, item
->IsExpanded() ? kThemeDisclosureDown
: kThemeDisclosureRight
,
228 kThemeAdornmentNone
};
229 DrawThemeButton( &bounds
, kThemeDisclosureButton
,
230 &info
, NULL
, NULL
, NULL
, NULL
) ;
232 dc
.DrawBitmap(flags
& wxCONTROL_EXPANDED
? m_bmpTreeExpanded
233 : m_bmpTreeCollapsed
,
234 rect
.x
, rect
.y
, true /* use mask */);
239 wxRendererMac::DrawSplitterSash(wxWindow
*win
,
243 wxOrientation orient
,
246 #if ( TARGET_API_MAC_OSX == 1 ) && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 )
247 if ( UMAGetSystemVersion() >= 0x1030 )
249 bool hasMetal
= win
->MacGetTopLevelWindow()->MacGetMetalAppearance() ;
251 GetThemeMetric( kThemeMetricSmallPaneSplitterHeight
, &height
) ;
252 HIRect splitterRect
;
253 if ( orient
== wxVERTICAL
)
254 splitterRect
= CGRectMake( position
, 0 , height
, size
.y
);
256 splitterRect
= CGRectMake( 0 , position
, size
.x
, height
);
257 HIViewConvertRect( &splitterRect
, (HIViewRef
) win
->GetHandle() , (HIViewRef
) win
->MacGetTopLevelWindow()->GetHandle() ) ;
259 // under compositing we should only draw when called by the OS, otherwise just issue a redraw command
260 // strange redraw errors occur if we don't do this
262 if ( dc
.IsKindOf( CLASSINFO( wxPaintDC
) ) == false )
264 Rect r
= { (short) splitterRect
.origin
.y
, (short) splitterRect
.origin
.x
,
265 (short) (splitterRect
.origin
.y
+ splitterRect
.size
.height
) , (short) (splitterRect
.origin
.x
+ splitterRect
.size
.width
) } ;
266 RgnHandle updateRgn
= NewRgn() ;
267 RectRgn( updateRgn
, &r
) ;
268 HIViewSetNeedsDisplayInRegion( (HIViewRef
) win
->GetHandle() , updateRgn
, true ) ;
269 DisposeRgn( updateRgn
) ;
273 CGContextRef cgContext
;
275 GetPortBounds( (CGrafPtr
) dc
.m_macPort
, &bounds
) ;
276 QDBeginCGContext( (CGrafPtr
) dc
.m_macPort
, &cgContext
) ;
277 CGContextTranslateCTM( cgContext
, 0 , bounds
.bottom
- bounds
.top
) ;
278 CGContextScaleCTM( cgContext
, 1 , -1 ) ;
281 HIThemeSplitterDrawInfo drawInfo
;
282 drawInfo
.version
= 0 ;
283 drawInfo
.state
= kThemeStateActive
;
284 drawInfo
.adornment
= hasMetal
? kHIThemeSplitterAdornmentMetal
: kHIThemeSplitterAdornmentNone
;
285 HIThemeDrawPaneSplitter( &splitterRect
, &drawInfo
, cgContext
, kHIThemeOrientationNormal
) ;
287 QDEndCGContext( (CGrafPtr
) dc
.m_macPort
, &cgContext
) ;
294 dc
.SetPen(*wxLIGHT_GREY_PEN
);
295 dc
.SetBrush(*wxWHITE_BRUSH
);
296 if ( orient
== wxVERTICAL
)
297 dc
.DrawRectangle(position
, 0, 7, size
.y
);
299 dc
.DrawRectangle(0, position
, size
.x
, 7);
301 // Do the gradient fill:
302 static int grayValues
[] =
304 0xA0, 0xF6, 0xED, 0xE4, 0xE2, 0xD0, 0xA0
306 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
307 if ( orient
== wxVERTICAL
)
310 for (i
=0; i
< (int)WXSIZEOF(grayValues
); i
++)
312 dc
.SetPen( wxPen( wxColour( grayValues
[i
] , grayValues
[i
] , grayValues
[i
] ),
314 dc
.DrawRectangle( position
+i
, 0, 1, size
.y
);
320 for (i
=0; i
< (int)WXSIZEOF(grayValues
); i
++)
322 dc
.SetPen( wxPen( wxColour( grayValues
[i
] , grayValues
[i
] , grayValues
[i
] ),
324 dc
.DrawRectangle( 0, position
+i
, size
.x
, 1 );