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: renderer.cpp 54486 2008-07-04 14:23:38Z SC $ 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/graphics.h" 30#include "wx/mac/uma.h" 31 32 33// check if we're currently in a paint event 34inline bool wxInPaintEvent(wxWindow* win, wxDC& dc) 35{ 36 return 37#if wxMAC_USE_CORE_GRAPHICS 38 win->MacGetCGContextRef() != NULL || 39#endif 40 // wxMemoryDC derives from wxPaintDC so it is okay too. 41 dc.IsKindOf( CLASSINFO(wxPaintDC) ); 42} 43 44 45 46class WXDLLEXPORT wxRendererMac : public wxDelegateRendererNative 47{ 48public: 49 // draw the header control button (used by wxListCtrl) 50 virtual int DrawHeaderButton( wxWindow *win, 51 wxDC& dc, 52 const wxRect& rect, 53 int flags = 0, 54 wxHeaderSortIconType sortArrow = wxHDR_SORT_ICON_NONE, 55 wxHeaderButtonParams* params = NULL ); 56 57 virtual int GetHeaderButtonHeight(wxWindow *win); 58 59 // draw the expanded/collapsed icon for a tree control item 60 virtual void DrawTreeItemButton( wxWindow *win, 61 wxDC& dc, 62 const wxRect& rect, 63 int flags = 0 ); 64 65 // draw a (vertical) sash 66 virtual void DrawSplitterSash( wxWindow *win, 67 wxDC& dc, 68 const wxSize& size, 69 wxCoord position, 70 wxOrientation orient, 71 int flags = 0 ); 72 73 virtual void DrawCheckBox(wxWindow *win, 74 wxDC& dc, 75 const wxRect& rect, 76 int flags = 0); 77 78 virtual void DrawComboBoxDropButton(wxWindow *win, 79 wxDC& dc, 80 const wxRect& rect, 81 int flags = 0); 82 83 virtual void DrawPushButton(wxWindow *win, 84 wxDC& dc, 85 const wxRect& rect, 86 int flags = 0); 87 88 virtual void DrawItemSelectionRect(wxWindow *win, 89 wxDC& dc, 90 const wxRect& rect, 91 int flags = 0); 92 93private: 94 void DrawMacThemeButton(wxWindow *win, 95 wxDC& dc, 96 const wxRect& rect, 97 int flags, 98 int kind, 99 int adornment); 100 101 // the tree buttons 102 wxBitmap m_bmpTreeExpanded; 103 wxBitmap m_bmpTreeCollapsed; 104 105 friend void wxRenderer_DrawRadioButton(wxWindow* win, wxDC& dc, 106 const wxRect& rect, int flags); 107 friend void wxRenderer_DrawChoice(wxWindow* win, wxDC& dc, 108 const wxRect& rect, int flags); 109 friend void wxRenderer_DrawComboBox(wxWindow* win, wxDC& dc, 110 const wxRect& rect, int flags); 111}; 112 113// ============================================================================ 114// implementation 115// ============================================================================ 116 117// static 118wxRendererNative& wxRendererNative::GetDefault() 119{ 120 static wxRendererMac s_rendererMac; 121 122 return s_rendererMac; 123} 124 125int wxRendererMac::DrawHeaderButton( wxWindow *win, 126 wxDC& dc, 127 const wxRect& rect, 128 int flags, 129 wxHeaderSortIconType sortArrow, 130 wxHeaderButtonParams* params ) 131{ 132#if !wxMAC_USE_CORE_GRAPHICS 133 const wxCoord x = dc.LogicalToDeviceX(rect.x); 134 const wxCoord y = dc.LogicalToDeviceY(rect.y); 135 const wxCoord w = dc.LogicalToDeviceXRel(rect.width); 136 const wxCoord h = dc.LogicalToDeviceYRel(rect.height); 137#else 138 // now the wxGCDC is using native transformations 139 const wxCoord x = rect.x; 140 const wxCoord y = rect.y; 141 const wxCoord w = rect.width; 142 const wxCoord h = rect.height; 143#endif 144 145 dc.SetBrush( *wxTRANSPARENT_BRUSH ); 146 147 HIRect headerRect = CGRectMake( x, y, w, h ); 148 if ( !wxInPaintEvent(win, dc) ) 149 { 150 Rect r = 151 { 152 (short) headerRect.origin.y, (short) headerRect.origin.x, 153 (short) (headerRect.origin.y + headerRect.size.height), 154 (short) (headerRect.origin.x + headerRect.size.width) 155 }; 156 157 RgnHandle updateRgn = NewRgn(); 158 RectRgn( updateRgn, &r ); 159 HIViewSetNeedsDisplayInRegion( (HIViewRef) win->GetHandle(), updateRgn, true ); 160 DisposeRgn( updateRgn ); 161 } 162 else 163 { 164 CGContextRef cgContext; 165 166#if wxMAC_USE_CORE_GRAPHICS 167 cgContext = (CGContextRef) dc.GetGraphicsContext()->GetNativeContext(); 168#else 169 Rect bounds; 170 171 GetPortBounds( (CGrafPtr) dc.m_macPort, &bounds ); 172 QDBeginCGContext( (CGrafPtr) dc.m_macPort, &cgContext ); 173 174 CGContextTranslateCTM( cgContext, 0, bounds.bottom - bounds.top ); 175 CGContextScaleCTM( cgContext, 1, -1 ); 176 177 HIShapeRef shape = HIShapeCreateWithQDRgn( (RgnHandle) dc.m_macCurrentClipRgn ); 178 if ( shape != 0 ) 179 { 180 HIShapeReplacePathInCGContext( shape , cgContext ); 181 CFRelease( shape ); 182 CGContextClip( cgContext ); 183 } 184 HIViewConvertRect( &headerRect, (HIViewRef) win->GetHandle(), (HIViewRef) win->MacGetTopLevelWindow()->GetHandle() ); 185#endif 186 187 { 188 HIThemeButtonDrawInfo drawInfo; 189 HIRect labelRect; 190 191 memset( &drawInfo, 0, sizeof(drawInfo) ); 192 drawInfo.version = 0; 193 drawInfo.kind = kThemeListHeaderButton; 194 drawInfo.state = (flags & wxCONTROL_DISABLED) ? kThemeStateInactive : kThemeStateActive; 195 drawInfo.value = (flags & wxCONTROL_SELECTED) ? kThemeButtonOn : kThemeButtonOff; 196 drawInfo.adornment = kThemeAdornmentNone; 197 198 // The down arrow is drawn automatically, change it to an up arrow if needed. 199 if ( sortArrow == wxHDR_SORT_ICON_UP ) 200 drawInfo.adornment = kThemeAdornmentHeaderButtonSortUp; 201 202 HIThemeDrawButton( &headerRect, &drawInfo, cgContext, kHIThemeOrientationNormal, &labelRect ); 203 204 // If we don't want any arrows we need to draw over the one already there 205 if ( (flags & wxCONTROL_SELECTED) && (sortArrow == wxHDR_SORT_ICON_NONE) ) 206 { 207 // clip to the header rectangle 208 CGContextSaveGState( cgContext ); 209 CGContextClipToRect( cgContext, headerRect ); 210 // but draw bigger than that so the arrow will get clipped off 211 headerRect.size.width += 25; 212 HIThemeDrawButton( &headerRect, &drawInfo, cgContext, kHIThemeOrientationNormal, &labelRect ); 213 CGContextRestoreGState( cgContext ); 214 } 215 } 216 217#if wxMAC_USE_CORE_GRAPHICS 218#else 219 QDEndCGContext( (CGrafPtr) dc.m_macPort, &cgContext ); 220#endif 221 } 222 223 // Reserve room for the arrows before writing the label, and turn off the 224 // flags we've already handled 225 wxRect newRect(rect); 226 if ( (flags & wxCONTROL_SELECTED) && (sortArrow != wxHDR_SORT_ICON_NONE) ) 227 { 228 newRect.width -= 12; 229 sortArrow = wxHDR_SORT_ICON_NONE; 230 } 231 flags &= ~wxCONTROL_SELECTED; 232 233 return DrawHeaderButtonContents(win, dc, newRect, flags, sortArrow, params); 234} 235 236 237int wxRendererMac::GetHeaderButtonHeight(wxWindow* WXUNUSED(win)) 238{ 239 SInt32 standardHeight; 240 OSStatus errStatus; 241 242 errStatus = GetThemeMetric( kThemeMetricListHeaderHeight, &standardHeight ); 243 if (errStatus == noErr) 244 { 245 return standardHeight; 246 } 247 return -1; 248} 249 250void wxRendererMac::DrawTreeItemButton( wxWindow *win, 251 wxDC& dc, 252 const wxRect& rect, 253 int flags ) 254{ 255#if !wxMAC_USE_CORE_GRAPHICS 256 const wxCoord x = dc.LogicalToDeviceX(rect.x); 257 const wxCoord y = dc.LogicalToDeviceY(rect.y); 258 const wxCoord w = dc.LogicalToDeviceXRel(rect.width); 259 const wxCoord h = dc.LogicalToDeviceYRel(rect.height); 260#else 261 // now the wxGCDC is using native transformations 262 const wxCoord x = rect.x; 263 const wxCoord y = rect.y; 264 const wxCoord w = rect.width; 265 const wxCoord h = rect.height; 266#endif 267 268 dc.SetBrush( *wxTRANSPARENT_BRUSH ); 269 270 HIRect headerRect = CGRectMake( x, y, w, h ); 271 if ( !wxInPaintEvent(win, dc) ) 272 { 273 Rect r = 274 { 275 (short) headerRect.origin.y, (short) headerRect.origin.x, 276 (short) (headerRect.origin.y + headerRect.size.height), 277 (short) (headerRect.origin.x + headerRect.size.width) 278 }; 279 280 RgnHandle updateRgn = NewRgn(); 281 RectRgn( updateRgn, &r ); 282 HIViewSetNeedsDisplayInRegion( (HIViewRef) win->GetHandle(), updateRgn, true ); 283 DisposeRgn( updateRgn ); 284 } 285 else 286 { 287 CGContextRef cgContext; 288 289#if wxMAC_USE_CORE_GRAPHICS 290 cgContext = (CGContextRef) dc.GetGraphicsContext()->GetNativeContext(); 291#else 292 Rect bounds; 293 294 GetPortBounds( (CGrafPtr) dc.m_macPort, &bounds ); 295 QDBeginCGContext( (CGrafPtr) dc.m_macPort, &cgContext ); 296 297 CGContextTranslateCTM( cgContext, 0, bounds.bottom - bounds.top ); 298 CGContextScaleCTM( cgContext, 1, -1 ); 299 300 HIShapeReplacePathInCGContext( HIShapeCreateWithQDRgn( (RgnHandle) dc.m_macCurrentClipRgn ), cgContext ); 301 CGContextClip( cgContext ); 302 HIViewConvertRect( &headerRect, (HIViewRef) win->GetHandle(), (HIViewRef) win->MacGetTopLevelWindow()->GetHandle() ); 303#endif 304 305 { 306 HIThemeButtonDrawInfo drawInfo; 307 HIRect labelRect; 308 309 memset( &drawInfo, 0, sizeof(drawInfo) ); 310 drawInfo.version = 0; 311 drawInfo.kind = kThemeDisclosureButton; 312 drawInfo.state = (flags & wxCONTROL_DISABLED) ? kThemeStateInactive : kThemeStateActive; 313 // Apple mailing list posts say to use the arrow adornment constants, but those don't work. 314 // We need to set the value using the 'old' DrawThemeButton constants instead. 315 drawInfo.value = (flags & wxCONTROL_EXPANDED) ? kThemeDisclosureDown : kThemeDisclosureRight; 316 drawInfo.adornment = kThemeAdornmentNone; 317 318 HIThemeDrawButton( &headerRect, &drawInfo, cgContext, kHIThemeOrientationNormal, &labelRect ); 319 320 } 321 322#if wxMAC_USE_CORE_GRAPHICS 323#else 324 QDEndCGContext( (CGrafPtr) dc.m_macPort, &cgContext ); 325#endif 326 } 327} 328 329void wxRendererMac::DrawSplitterSash( wxWindow *win, 330 wxDC& dc, 331 const wxSize& size, 332 wxCoord position, 333 wxOrientation orient, 334 int WXUNUSED(flags) ) 335{ 336 bool hasMetal = win->MacGetTopLevelWindow()->MacGetMetalAppearance(); 337 SInt32 height; 338 GetThemeMetric( kThemeMetricSmallPaneSplitterHeight, &height ); 339 HIRect splitterRect; 340 if (orient == wxVERTICAL) 341 splitterRect = CGRectMake( position, 0, height, size.y ); 342 else 343 splitterRect = CGRectMake( 0, position, size.x, height ); 344 345#if !wxMAC_USE_CORE_GRAPHICS 346 HIViewConvertRect( 347 &splitterRect, 348 (HIViewRef) win->GetHandle(), 349 (HIViewRef) win->MacGetTopLevelWindow()->GetHandle() ); 350#endif 351 352 // under compositing we should only draw when called by the OS, otherwise just issue a redraw command 353 // strange redraw errors occur if we don't do this 354 355 if ( !wxInPaintEvent(win, dc) ) 356 { 357 Rect r = 358 { 359 (short) splitterRect.origin.y, 360 (short) splitterRect.origin.x, 361 (short) (splitterRect.origin.y + splitterRect.size.height), 362 (short) (splitterRect.origin.x + splitterRect.size.width) 363 }; 364 365 RgnHandle updateRgn = NewRgn(); 366 RectRgn( updateRgn, &r ); 367 HIViewSetNeedsDisplayInRegion( (HIViewRef) win->GetHandle(), updateRgn, true ); 368 DisposeRgn( updateRgn ); 369 } 370 else 371 { 372 CGContextRef cgContext; 373 374#if wxMAC_USE_CORE_GRAPHICS 375 cgContext = (CGContextRef) dc.GetGraphicsContext()->GetNativeContext(); 376#else 377 Rect bounds; 378 GetPortBounds( (CGrafPtr) dc.m_macPort, &bounds ); 379 QDBeginCGContext( (CGrafPtr) dc.m_macPort, &cgContext ); 380 CGContextTranslateCTM( cgContext, 0, bounds.bottom - bounds.top ); 381 CGContextScaleCTM( cgContext, 1, -1 ); 382#endif 383 384 HIThemeSplitterDrawInfo drawInfo; 385 drawInfo.version = 0; 386 drawInfo.state = kThemeStateActive; 387 drawInfo.adornment = hasMetal ? kHIThemeSplitterAdornmentMetal : kHIThemeSplitterAdornmentNone; 388 HIThemeDrawPaneSplitter( &splitterRect, &drawInfo, cgContext, kHIThemeOrientationNormal ); 389 390#if wxMAC_USE_CORE_GRAPHICS 391#else 392 QDEndCGContext( (CGrafPtr) dc.m_macPort, &cgContext ); 393#endif 394 } 395} 396 397void 398wxRendererMac::DrawItemSelectionRect(wxWindow *win, 399 wxDC& dc, 400 const wxRect& rect, 401 int flags ) 402{ 403 RGBColor selColor; 404 if (flags & wxCONTROL_SELECTED) 405 { 406 if (flags & wxCONTROL_FOCUSED) 407 GetThemeBrushAsColor(kThemeBrushAlternatePrimaryHighlightColor, 32, true, &selColor); 408 else 409 GetThemeBrushAsColor(kThemeBrushSecondaryHighlightColor, 32, true, &selColor); 410 } 411 412 wxBrush selBrush = wxBrush( wxColour( selColor.red >> 8, selColor.green >> 8, selColor.blue >> 8 ), wxSOLID ); 413 414 dc.SetPen( *wxTRANSPARENT_PEN ); 415 dc.SetBrush( selBrush ); 416 dc.DrawRectangle( rect ); 417} 418 419 420void 421wxRendererMac::DrawMacThemeButton(wxWindow *win, 422 wxDC& dc, 423 const wxRect& rect, 424 int flags, 425 int kind, 426 int adornment) 427{ 428#if !wxMAC_USE_CORE_GRAPHICS 429 const wxCoord x = dc.LogicalToDeviceX(rect.x); 430 const wxCoord y = dc.LogicalToDeviceY(rect.y); 431 const wxCoord w = dc.LogicalToDeviceXRel(rect.width); 432 const wxCoord h = dc.LogicalToDeviceYRel(rect.height); 433#else 434 // now the wxGCDC is using native transformations 435 const wxCoord x = rect.x; 436 const wxCoord y = rect.y; 437 const wxCoord w = rect.width; 438 const wxCoord h = rect.height; 439#endif 440 441 dc.SetBrush( *wxTRANSPARENT_BRUSH ); 442 443 HIRect headerRect = CGRectMake( x, y, w, h ); 444 if ( !wxInPaintEvent(win, dc) ) 445 { 446 Rect r = 447 { 448 (short) headerRect.origin.y, (short) headerRect.origin.x, 449 (short) (headerRect.origin.y + headerRect.size.height), 450 (short) (headerRect.origin.x + headerRect.size.width) 451 }; 452 453 RgnHandle updateRgn = NewRgn(); 454 RectRgn( updateRgn, &r ); 455 HIViewSetNeedsDisplayInRegion( (HIViewRef) win->GetHandle(), updateRgn, true ); 456 DisposeRgn( updateRgn ); 457 } 458 else 459 { 460 CGContextRef cgContext; 461 462#if wxMAC_USE_CORE_GRAPHICS 463 cgContext = (CGContextRef) dc.GetGraphicsContext()->GetNativeContext(); 464#else 465 Rect bounds; 466 467 GetPortBounds( (CGrafPtr) dc.m_macPort, &bounds ); 468 QDBeginCGContext( (CGrafPtr) dc.m_macPort, &cgContext ); 469 470 CGContextTranslateCTM( cgContext, 0, bounds.bottom - bounds.top ); 471 CGContextScaleCTM( cgContext, 1, -1 ); 472 473 HIShapeReplacePathInCGContext( HIShapeCreateWithQDRgn( (RgnHandle) dc.m_macCurrentClipRgn ), cgContext ); 474 CGContextClip( cgContext ); 475 HIViewConvertRect( &headerRect, (HIViewRef) win->GetHandle(), (HIViewRef) win->MacGetTopLevelWindow()->GetHandle() ); 476#endif 477 478 { 479 HIThemeButtonDrawInfo drawInfo; 480 HIRect labelRect; 481 482 memset( &drawInfo, 0, sizeof(drawInfo) ); 483 drawInfo.version = 0; 484 drawInfo.kind = kind; 485 drawInfo.state = (flags & wxCONTROL_DISABLED) ? kThemeStateInactive : kThemeStateActive; 486 drawInfo.value = (flags & wxCONTROL_SELECTED) ? kThemeButtonOn : kThemeButtonOff; 487 if (flags & wxCONTROL_UNDETERMINED) 488 drawInfo.value = kThemeButtonMixed; 489 drawInfo.adornment = adornment; 490 if (flags & wxCONTROL_FOCUSED) 491 drawInfo.adornment |= kThemeAdornmentFocus; 492 493 HIThemeDrawButton( &headerRect, &drawInfo, cgContext, kHIThemeOrientationNormal, &labelRect ); 494 } 495 496#if wxMAC_USE_CORE_GRAPHICS 497#else 498 QDEndCGContext( (CGrafPtr) dc.m_macPort, &cgContext ); 499#endif 500 } 501} 502 503void 504wxRendererMac::DrawCheckBox(wxWindow *win, 505 wxDC& dc, 506 const wxRect& rect, 507 int flags) 508{ 509 int kind; 510 511 if (win->GetWindowVariant() == wxWINDOW_VARIANT_SMALL || 512 (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_SMALL)) 513 kind = kThemeSmallCheckBox; 514 else if (win->GetWindowVariant() == wxWINDOW_VARIANT_MINI || 515 (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_MINI)) 516 kind = kThemeMiniCheckBox; 517 else 518 kind = kThemeCheckBox; 519 520 if (flags & wxCONTROL_CHECKED) 521 flags |= wxCONTROL_SELECTED; 522 523 DrawMacThemeButton(win, dc, rect, flags, 524 kind, kThemeAdornmentNone); 525} 526 527void 528wxRendererMac::DrawComboBoxDropButton(wxWindow *win, 529 wxDC& dc, 530 const wxRect& rect, 531 int flags) 532{ 533 int kind; 534 if (win->GetWindowVariant() == wxWINDOW_VARIANT_SMALL || (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_SMALL)) 535 kind = kThemeArrowButtonSmall; 536 else if (win->GetWindowVariant() == wxWINDOW_VARIANT_MINI || (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_MINI)) 537 kind = kThemeArrowButtonMini; 538 else 539 kind = kThemeArrowButton; 540 541 DrawMacThemeButton(win, dc, rect, flags, 542 kind, kThemeAdornmentArrowDownArrow); 543} 544 545void 546wxRendererMac::DrawPushButton(wxWindow *win, 547 wxDC& dc, 548 const wxRect& rect, 549 int flags) 550{ 551 int kind; 552#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 553 if (win->GetWindowVariant() == wxWINDOW_VARIANT_SMALL || (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_SMALL)) 554 kind = kThemeBevelButtonSmall; 555 // There is no kThemeBevelButtonMini, but in this case, use Small 556 else if (win->GetWindowVariant() == wxWINDOW_VARIANT_MINI || (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_MINI)) 557 kind = kThemeBevelButtonSmall; 558 else 559#endif 560 kind = kThemeBevelButton; 561 562 DrawMacThemeButton(win, dc, rect, flags, 563 kind, kThemeAdornmentNone); 564} 565 566 567 568 569void wxRenderer_DrawChoice(wxWindow* win, wxDC& dc, 570 const wxRect& rect, int flags) 571{ 572 wxRendererMac& r = (wxRendererMac&)wxRendererNative::Get(); 573 int kind; 574 575 if (win->GetWindowVariant() == wxWINDOW_VARIANT_SMALL || 576 (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_SMALL)) 577 kind = kThemePopupButtonSmall; 578 else if (win->GetWindowVariant() == wxWINDOW_VARIANT_MINI || 579 (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_MINI)) 580 kind = kThemePopupButtonMini; 581 else 582 kind = kThemePopupButton; 583 584 r.DrawMacThemeButton(win, dc, rect, flags, kind, kThemeAdornmentNone); 585} 586 587 588void wxRenderer_DrawComboBox(wxWindow* win, wxDC& dc, 589 const wxRect& rect, int flags) 590{ 591 wxRendererMac& r = (wxRendererMac&)wxRendererNative::Get(); 592 int kind; 593 594 if (win->GetWindowVariant() == wxWINDOW_VARIANT_SMALL || 595 (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_SMALL)) 596 kind = kThemeComboBoxSmall; 597 else if (win->GetWindowVariant() == wxWINDOW_VARIANT_MINI || 598 (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_MINI)) 599 kind = kThemeComboBoxMini; 600 else 601 kind = kThemeComboBox; 602 603 r.DrawMacThemeButton(win, dc, rect, flags, kind, kThemeAdornmentNone); 604} 605 606void wxRenderer_DrawRadioButton(wxWindow* win, wxDC& dc, 607 const wxRect& rect, int flags) 608{ 609 wxRendererMac& r = (wxRendererMac&)wxRendererNative::Get(); 610 int kind; 611 612 if (win->GetWindowVariant() == wxWINDOW_VARIANT_SMALL || 613 (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_SMALL)) 614 kind = kThemeSmallRadioButton; 615 else if (win->GetWindowVariant() == wxWINDOW_VARIANT_MINI || 616 (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_MINI)) 617 kind = kThemeMiniRadioButton; 618 else 619 kind = kThemeRadioButton; 620 621 if (flags & wxCONTROL_CHECKED) 622 flags |= wxCONTROL_SELECTED; 623 624 r.DrawMacThemeButton(win, dc, rect, flags, 625 kind, kThemeAdornmentNone); 626} 627 628 629 630void wxRenderer_DrawTextCtrl(wxWindow* win, wxDC& dc, 631 const wxRect& rect, int flags) 632{ 633#if !wxMAC_USE_CORE_GRAPHICS 634 const wxCoord x = dc.LogicalToDeviceX(rect.x); 635 const wxCoord y = dc.LogicalToDeviceY(rect.y); 636 const wxCoord w = dc.LogicalToDeviceXRel(rect.width); 637 const wxCoord h = dc.LogicalToDeviceYRel(rect.height); 638#else 639 // now the wxGCDC is using native transformations 640 const wxCoord x = rect.x; 641 const wxCoord y = rect.y; 642 const wxCoord w = rect.width; 643 const wxCoord h = rect.height; 644#endif 645 646 dc.SetBrush( *wxWHITE_BRUSH ); 647 dc.SetPen( *wxTRANSPARENT_PEN ); 648 dc.DrawRectangle(rect); 649 650 dc.SetBrush( *wxTRANSPARENT_BRUSH ); 651 652 HIRect hiRect = CGRectMake( x, y, w, h ); 653 if ( !wxInPaintEvent(win, dc) ) 654 { 655 Rect r = 656 { 657 (short) hiRect.origin.y, (short) hiRect.origin.x, 658 (short) (hiRect.origin.y + hiRect.size.height), 659 (short) (hiRect.origin.x + hiRect.size.width) 660 }; 661 662 RgnHandle updateRgn = NewRgn(); 663 RectRgn( updateRgn, &r ); 664 HIViewSetNeedsDisplayInRegion( (HIViewRef) win->GetHandle(), updateRgn, true ); 665 DisposeRgn( updateRgn ); 666 } 667 else 668 { 669 CGContextRef cgContext; 670 671#if wxMAC_USE_CORE_GRAPHICS 672 cgContext = (CGContextRef) dc.GetGraphicsContext()->GetNativeContext(); 673#else 674 Rect bounds; 675 676 GetPortBounds( (CGrafPtr) dc.m_macPort, &bounds ); 677 QDBeginCGContext( (CGrafPtr) dc.m_macPort, &cgContext ); 678 679 CGContextTranslateCTM( cgContext, 0, bounds.bottom - bounds.top ); 680 CGContextScaleCTM( cgContext, 1, -1 ); 681 682 HIShapeReplacePathInCGContext( HIShapeCreateWithQDRgn( (RgnHandle) dc.m_macCurrentClipRgn ), cgContext ); 683 CGContextClip( cgContext ); 684 HIViewConvertRect( &hiRect, (HIViewRef) win->GetHandle(), (HIViewRef) win->MacGetTopLevelWindow()->GetHandle() ); 685#endif 686 687 { 688 HIThemeFrameDrawInfo drawInfo; 689 690 memset( &drawInfo, 0, sizeof(drawInfo) ); 691 drawInfo.version = 0; 692 drawInfo.kind = kHIThemeFrameTextFieldSquare; 693 drawInfo.state = (flags & wxCONTROL_DISABLED) ? kThemeStateInactive : kThemeStateActive; 694 if (flags & wxCONTROL_FOCUSED) 695 drawInfo.isFocused = true; 696 697 HIThemeDrawFrame( &hiRect, &drawInfo, cgContext, kHIThemeOrientationNormal); 698 } 699 700#if wxMAC_USE_CORE_GRAPHICS 701#else 702 QDEndCGContext( (CGrafPtr) dc.m_macPort, &cgContext ); 703#endif 704 } 705} 706 707 708