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/mac/uma.h"
37 // ----------------------------------------------------------------------------
38 // wxRendererMac: our wxRendererNative implementation
39 // ----------------------------------------------------------------------------
41 class WXDLLEXPORT wxRendererMac
: public wxDelegateRendererNative
44 // draw the header control button (used by wxListCtrl)
45 virtual void DrawHeaderButton(wxWindow
*win
,
50 // draw the expanded/collapsed icon for a tree control item
51 virtual void DrawTreeItemButton(wxWindow
*win
,
56 // draw a (vertical) sash
57 virtual void DrawSplitterSash(wxWindow
*win
,
66 wxBitmap m_bmpTreeExpanded
,
70 // ----------------------------------------------------------------------------
72 // ----------------------------------------------------------------------------
75 static const char *aqua_arrow_right_xpm
[] = {
76 /* columns rows colors chars-per-pixel */
97 static const char *aqua_arrow_down_xpm
[] = {
98 /* columns rows colors chars-per-pixel */
118 // ============================================================================
120 // ============================================================================
123 wxRendererNative
& wxRendererNative::GetDefault()
125 static wxRendererMac s_rendererMac
;
127 return s_rendererMac
;
131 wxRendererMac::DrawHeaderButton(wxWindow
*win
,
136 const int CORNER
= 1;
138 const wxCoord x
= rect
.x
-1,
144 wxGetOsVersion( &major
, &minor
);
146 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
150 dc
.SetPen( wxPen( wxColour( 0xC5 , 0xC5 , 0xC5 ) , 1 , wxSOLID
) );
151 dc
.DrawRectangle( x
, y
+CORNER
, 1, h
-CORNER
); // left
152 // The right border is overdrawn by the left border of the right neighbouring
153 // header (to maintain a proper single pixel border). Except for the
154 // rightmost header of the listctrl.
155 dc
.DrawRectangle( x
+w
+(CORNER
*2), y
+CORNER
, 1, h
-CORNER
); // right
156 dc
.SetPen( wxPen( wxColour( 0xB1 , 0xB1 , 0xB1 ) , 1 , wxSOLID
) );
157 dc
.DrawRectangle( x
, y
+h
, w
+(CORNER
*3), 1 ); // bottom
158 dc
.DrawRectangle( x
, y
, w
+(CORNER
*3), 1 ); // top
160 // Do a fill of the interior for background:
161 dc
.SetPen( wxPen( wxColour( 0xF6 , 0xF6 , 0xF6 ) , 1 , wxSOLID
) );
162 dc
.DrawRectangle( x
+CORNER
, y
+CORNER
, w
+CORNER
, h
-CORNER
);
164 // Do the gradient fill:
165 static int grayValues
[] =
167 0xF6, 0xF2, 0xEF, 0xED, 0xED, 0xEB, 0xEA, 0xEA, 0xE8,
168 0xE8, 0xE2, 0xE5, 0xE8, 0xEB, 0xEF, 0xF2, 0xFD
171 for (i
=0; i
< h
&& i
< (int)WXSIZEOF(grayValues
); i
++)
173 dc
.SetPen( wxPen( wxColour( grayValues
[i
] , grayValues
[i
] , grayValues
[i
] ),
175 dc
.DrawRectangle( x
+CORNER
, y
+CORNER
+i
, w
+CORNER
, 1 );
180 dc
.SetPen( wxPen( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNSHADOW
) , 1 , wxSOLID
) );
181 dc
.DrawLine( x
+w
-CORNER
+1, y
, x
+w
, y
+h
); // right (outer)
182 dc
.DrawRectangle( x
, y
+h
, w
+1, 1 ); // bottom (outer)
184 wxPen
pen( wxColour( 0x88 , 0x88 , 0x88 ), 1, wxSOLID
);
187 dc
.DrawLine( x
+w
-CORNER
, y
, x
+w
-1, y
+h
); // right (inner)
188 dc
.DrawRectangle( x
+1, y
+h
-1, w
-2, 1 ); // bottom (inner)
190 dc
.SetPen( *wxWHITE_PEN
);
191 dc
.DrawRectangle( x
, y
, w
-CORNER
+1, 1 ); // top (outer)
192 dc
.DrawRectangle( x
, y
, 1, h
); // left (outer)
193 dc
.DrawLine( x
, y
+h
-1, x
+1, y
+h
-1 );
194 dc
.DrawLine( x
+w
-1, y
, x
+w
-1, y
+1 );
199 wxRendererMac::DrawTreeItemButton(wxWindow
*win
,
204 // init the buttons on demand
205 if ( !m_bmpTreeExpanded
.Ok() )
207 m_bmpTreeExpanded
= wxBitmap(aqua_arrow_down_xpm
);
208 m_bmpTreeCollapsed
= wxBitmap(aqua_arrow_right_xpm
);
213 // VZ: this is the old code from treectlg.cpp which apparently doesn't work
214 // but I kept it here just in case it is needed -- if not, please
216 #if 0 // def __WXMAC__
217 wxMacPortSetter
helper(&dc
) ;
218 wxMacWindowClipper
clipper(this) ;
219 wxDC::MacSetupBackgroundForCurrentPort( MacGetBackgroundBrush() ) ;
222 int loc_y
= y_mid
- 6 ;
223 MacWindowToRootWindow( & loc_x
, & loc_y
) ;
224 Rect bounds
= { loc_y
, loc_x
, loc_y
+ 18 , loc_x
+ 12 } ;
225 ThemeButtonDrawInfo info
= { kThemeStateActive
, item
->IsExpanded() ? kThemeDisclosureDown
: kThemeDisclosureRight
,
226 kThemeAdornmentNone
};
227 DrawThemeButton( &bounds
, kThemeDisclosureButton
,
228 &info
, NULL
, NULL
, NULL
, NULL
) ;
230 dc
.DrawBitmap(flags
& wxCONTROL_EXPANDED
? m_bmpTreeExpanded
231 : m_bmpTreeCollapsed
,
232 rect
.x
, rect
.y
, true /* use mask */);
237 wxRendererMac::DrawSplitterSash(wxWindow
*win
,
241 wxOrientation orient
,
244 #if ( TARGET_API_MAC_OSX == 1 ) && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 )
245 if ( UMAGetSystemVersion() >= 0x1030 )
247 bool hasMetal
= win
->MacGetTopLevelWindow()->MacGetMetalAppearance() ;
249 GetThemeMetric( kThemeMetricSmallPaneSplitterHeight
, &height
) ;
250 HIRect splitterRect
;
251 if ( orient
== wxVERTICAL
)
252 splitterRect
= CGRectMake( position
, 0 , height
, size
.y
);
254 splitterRect
= CGRectMake( 0 , position
, size
.x
, height
);
255 HIViewConvertRect( &splitterRect
, (HIViewRef
) win
->GetHandle() , (HIViewRef
) win
->MacGetTopLevelWindow()->GetHandle() ) ;
257 // under compositing we should only draw when called by the OS, otherwise just issue a redraw command
258 // strange redraw errors occur if we don't do this
260 if ( dc
.IsKindOf( CLASSINFO( wxPaintDC
) ) == false )
262 Rect r
= { (short) splitterRect
.origin
.y
, (short) splitterRect
.origin
.x
,
263 (short) (splitterRect
.origin
.y
+ splitterRect
.size
.height
) , (short) (splitterRect
.origin
.x
+ splitterRect
.size
.width
) } ;
264 RgnHandle updateRgn
= NewRgn() ;
265 RectRgn( updateRgn
, &r
) ;
266 HIViewSetNeedsDisplayInRegion( (HIViewRef
) win
->GetHandle() , updateRgn
, true ) ;
267 DisposeRgn( updateRgn
) ;
271 CGContextRef cgContext
;
273 GetPortBounds( (CGrafPtr
) dc
.m_macPort
, &bounds
) ;
274 QDBeginCGContext( (CGrafPtr
) dc
.m_macPort
, &cgContext
) ;
275 CGContextTranslateCTM( cgContext
, 0 , bounds
.bottom
- bounds
.top
) ;
276 CGContextScaleCTM( cgContext
, 1 , -1 ) ;
279 HIThemeSplitterDrawInfo drawInfo
;
280 drawInfo
.version
= 0 ;
281 drawInfo
.state
= kThemeStateActive
;
282 drawInfo
.adornment
= hasMetal
? kHIThemeSplitterAdornmentMetal
: kHIThemeSplitterAdornmentNone
;
283 HIThemeDrawPaneSplitter( &splitterRect
, &drawInfo
, cgContext
, kHIThemeOrientationNormal
) ;
285 QDEndCGContext( (CGrafPtr
) dc
.m_macPort
, &cgContext
) ;
292 dc
.SetPen(*wxLIGHT_GREY_PEN
);
293 dc
.SetBrush(*wxWHITE_BRUSH
);
294 if ( orient
== wxVERTICAL
)
295 dc
.DrawRectangle(position
, 0, 7, size
.y
);
297 dc
.DrawRectangle(0, position
, size
.x
, 7);
299 // Do the gradient fill:
300 static int grayValues
[] =
302 0xA0, 0xF6, 0xED, 0xE4, 0xE2, 0xD0, 0xA0
304 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
305 if ( orient
== wxVERTICAL
)
308 for (i
=0; i
< (int)WXSIZEOF(grayValues
); i
++)
310 dc
.SetPen( wxPen( wxColour( grayValues
[i
] , grayValues
[i
] , grayValues
[i
] ),
312 dc
.DrawRectangle( position
+i
, 0, 1, size
.y
);
318 for (i
=0; i
< (int)WXSIZEOF(grayValues
); i
++)
320 dc
.SetPen( wxPen( wxColour( grayValues
[i
] , grayValues
[i
] , grayValues
[i
] ),
322 dc
.DrawRectangle( 0, position
+i
, size
.x
, 1 );