// Author: Stefan Csomor
// Modified by:
// Created: 1998-01-01
-// RCS-ID: $Id$
// Copyright: (c) Stefan Csomor
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#include "wx/osx/uma.h"
#else
#include "wx/osx/private.h"
-// bring in themeing
+// bring in theming
#include <Carbon/Carbon.h>
#endif
#define wxMAC_DEBUG_REDRAW 0
#endif
+// Get the window with the focus
+WXWidget wxWidgetImpl::FindFocus()
+{
+ ControlRef control = NULL ;
+ GetKeyboardFocus( GetUserFocusWindow() , &control ) ;
+ return control;
+}
+
+// no compositing to take into account under carbon
+wxWidgetImpl* wxWidgetImpl::FindBestFromWXWidget(WXWidget control)
+{
+ return FindFromWXWidget(control);
+}
+
// ---------------------------------------------------------------------------
// Carbon Events
// ---------------------------------------------------------------------------
{
case kEventControlDraw :
{
- RgnHandle updateRgn = NULL ;
- RgnHandle allocatedRgn = NULL ;
+ HIShapeRef updateRgn = NULL ;
+ HIMutableShapeRef allocatedRgn = NULL ;
wxRegion visRegion = thisWindow->MacGetVisibleRegion() ;
- if ( cEvent.GetParameter<RgnHandle>(kEventParamRgnHandle, &updateRgn) != noErr )
+ // according to the docs: redraw entire control if param not present
+ if ( cEvent.GetParameter<HIShapeRef>(kEventParamShape, &updateRgn) != noErr )
{
- HIShapeGetAsQDRgn( visRegion.GetWXHRGN(), updateRgn );
+ updateRgn = visRegion.GetWXHRGN();
}
else
{
if ( thisWindow->MacGetLeftBorderSize() != 0 || thisWindow->MacGetTopBorderSize() != 0 )
{
// as this update region is in native window locals we must adapt it to wx window local
- allocatedRgn = NewRgn() ;
- CopyRgn( updateRgn , allocatedRgn ) ;
-
+ allocatedRgn = HIShapeCreateMutableCopy(updateRgn);
+ HIShapeOffset(allocatedRgn, thisWindow->MacGetLeftBorderSize() , thisWindow->MacGetTopBorderSize());
// hide the given region by the new region that must be shifted
- OffsetRgn( allocatedRgn , thisWindow->MacGetLeftBorderSize() , thisWindow->MacGetTopBorderSize() ) ;
updateRgn = allocatedRgn ;
}
}
#endif
{
- bool created = false ;
CGContextRef cgContext = NULL ;
OSStatus err = cEvent.GetParameter<CGContextRef>(kEventParamCGContextRef, &cgContext) ;
if ( err != noErr )
{
- wxFAIL_MSG("Unable to retrieve CGContextRef");
+ // for non-composite drawing, since we don't support it ourselves, send it through the
+ // the default handler
+ // CallNextEventHandler( handler,event ) ;
+ // result = noErr ;
+ if ( allocatedRgn )
+ CFRelease( allocatedRgn ) ;
+ break;
}
thisWindow->MacSetCGContextRef( cgContext ) ;
iter = iter->GetParent() ;
}
}
- CGContextSetAlpha( cgContext , alpha ) ;
+ CGContextSetAlpha( cgContext, alpha ) ;
if ( thisWindow->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT )
{
CGContextClearRect( cgContext, bounds );
}
-
-
- if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) )
- result = noErr ;
-
+ if ( !HIShapeIsEmpty(updateRgn) )
+ {
+ // refcount increase because wxRegion constructor takes ownership of the native region
+ CFRetain(updateRgn);
+ thisWindow->GetUpdateRegion() = wxRegion(updateRgn);
+ if ( !thisWindow->MacDoRedraw( cEvent.GetTicks() ) )
+ {
+ // for native controls: call their native paint method
+ if ( !thisWindow->MacIsUserPane() ||
+ ( thisWindow->IsTopLevel() && thisWindow->GetBackgroundStyle() == wxBG_STYLE_SYSTEM ) )
+ {
+ if ( thisWindow->GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT )
+ {
+ CallNextEventHandler( handler,event ) ;
+ result = noErr ;
+ }
+ }
+ }
+ else
+ {
+ result = noErr ;
+ }
+ thisWindow->MacPaintChildrenBorders();
+ }
thisWindow->MacSetCGContextRef( NULL ) ;
}
-
- if ( created )
- CGContextRelease( cgContext ) ;
}
if ( allocatedRgn )
- DisposeRgn( allocatedRgn ) ;
+ CFRelease( allocatedRgn ) ;
}
break ;
thisWindow->GetCaret()->OnKillFocus();
#endif
- wxLogTrace(_T("Focus"), _T("focus lost(%p)"), wx_static_cast(void*, thisWindow));
+ wxLogTrace(wxT("Focus"), wxT("focus lost(%p)"), static_cast<void*>(thisWindow));
// remove this as soon as posting the synthesized event works properly
static bool inKillFocusEvent = false ;
{
// set focus
// panel wants to track the window which was the last to have focus in it
- wxLogTrace(_T("Focus"), _T("focus set(%p)"), wx_static_cast(void*, thisWindow));
+ wxLogTrace(wxT("Focus"), wxT("focus set(%p)"), static_cast<void*>(thisWindow));
wxChildFocusEvent eventFocus((wxWindow*)thisWindow);
thisWindow->HandleWindowEvent(eventFocus);
if ( controlPart != kControlFocusNoPart )
{
targetFocusWindow = thisWindow;
- wxLogTrace(_T("Focus"), _T("focus to be set(%p)"), wx_static_cast(void*, thisWindow));
+ wxLogTrace(wxT("Focus"), wxT("focus to be set(%p)"), static_cast<void*>(thisWindow));
}
else
{
formerFocusWindow = thisWindow;
- wxLogTrace(_T("Focus"), _T("focus to be lost(%p)"), wx_static_cast(void*, thisWindow));
+ wxLogTrace(wxT("Focus"), wxT("focus to be lost(%p)"), static_cast<void*>(thisWindow));
}
-
+
ControlPartCode previousControlPart = 0;
verify_noerr( HIViewGetFocusPart(controlRef, &previousControlPart));
iEvent.SetParameter<EventTargetRef>( kEventParamPostTarget, typeEventTargetRef, GetControlEventTarget( controlRef ) );
iEvent.SetParameter<ControlPartCode>( kEventParamControlPreviousPart, typeControlPartCode, previousControlPart );
iEvent.SetParameter<ControlPartCode>( kEventParamControlCurrentPart, typeControlPartCode, currentControlPart );
-
+
#if 1
// TODO test this first, avoid double posts etc...
PostEventToQueue( GetMainEventQueue(), evRef , kEventPriorityHigh );
thisWindow->GetCaret()->OnKillFocus();
#endif
- wxLogTrace(_T("Focus"), _T("focus lost(%p)"), wx_static_cast(void*, thisWindow));
+ wxLogTrace(wxT("Focus"), wxT("focus lost(%p)"), static_cast<void*>(thisWindow));
static bool inKillFocusEvent = false ;
else
{
// panel wants to track the window which was the last to have focus in it
- wxLogTrace(_T("Focus"), _T("focus set(%p)"), wx_static_cast(void*, thisWindow));
+ wxLogTrace(wxT("Focus"), wxT("focus set(%p)"), static_cast<void*>(thisWindow));
wxChildFocusEvent eventFocus((wxWindow*)thisWindow);
thisWindow->HandleWindowEvent(eventFocus);
return result ;
}
-pascal OSStatus wxMacUnicodeTextEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
+WXDLLEXPORT pascal OSStatus wxMacUnicodeTextEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
{
OSStatus result = eventNotHandledErr ;
wxWindowMac* focus = (wxWindowMac*) data ;
uniChars = new wchar_t[ numChars ] ;
GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, NULL, dataSize , NULL , charBuf ) ;
charBuf[ numChars - 1 ] = 0;
-#if SIZEOF_WCHAR_T == 2
- uniChars = (wchar_t*) charBuf ;
-/* memcpy( uniChars , charBuf , numChars * 2 ) ;*/ // is there any point in copying charBuf over itself? (in fact, memcpy isn't even guaranteed to work correctly if the source and destination ranges overlap...)
-#else
// the resulting string will never have more chars than the utf16 version, so this is safe
wxMBConvUTF16 converter ;
numChars = converter.MB2WC( uniChars , (const char*)charBuf , numChars ) ;
-#endif
}
switch ( GetEventKind( event ) )
I don't have time to look into that right now.
-- CL
*/
- if ( wxTheApp->MacSendCharEvent(
- focus , message , 0 , when , 0 , 0 , uniChars[pos] ) )
+ if ( wxTheApp->MacSendCharEvent( focus , message , 0 , when , uniChars[pos] ) )
{
result = noErr ;
}
case kEventTextInputUnicodeForKeyEvent :
{
UInt32 keyCode, modifiers ;
- Point point ;
EventRef rawEvent ;
unsigned char charCode ;
GetEventParameter( event, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, sizeof(rawEvent), NULL, &rawEvent ) ;
- GetEventParameter( rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &charCode );
+ GetEventParameter( rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode );
GetEventParameter( rawEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
GetEventParameter( rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers );
- GetEventParameter( rawEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &point );
UInt32 message = (keyCode << 8) + charCode;
WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
wxTheApp->MacSetCurrentEvent( event , handler ) ;
- if ( wxTheApp->MacSendCharEvent(
- focus , message , modifiers , when , point.h , point.v , uniChars[pos] ) )
+ if ( wxTheApp->MacSendCharEvent( focus , message , modifiers , when , uniChars[pos] ) )
{
result = noErr ;
}
{
wxWindow* wx = wxFindWindowFromWXWidget( (WXWidget) control ) ;
if ( wx )
- wx->MacHandleControlClick( (WXWidget) control , partCode , true /* stillDown */ ) ;
+ {
+ wxEventType scrollEvent = wxEVT_NULL;
+ switch ( partCode )
+ {
+ case kControlUpButtonPart:
+ scrollEvent = wxEVT_SCROLL_LINEUP;
+ break;
+
+ case kControlDownButtonPart:
+ scrollEvent = wxEVT_SCROLL_LINEDOWN;
+ break;
+
+ case kControlPageUpPart:
+ scrollEvent = wxEVT_SCROLL_PAGEUP;
+ break;
+
+ case kControlPageDownPart:
+ scrollEvent = wxEVT_SCROLL_PAGEDOWN;
+ break;
+
+ case kControlIndicatorPart:
+ scrollEvent = wxEVT_SCROLL_THUMBTRACK;
+ // when this is called as a live proc, mouse is always still down
+ // so no need for thumbrelease
+ // scrollEvent = wxEVT_SCROLL_THUMBRELEASE;
+ break;
+ }
+ wx->TriggerScrollEvent(scrollEvent) ;
+ }
}
}
wxMAC_DEFINE_PROC_GETTER( ControlActionUPP , wxMacLiveScrollbarActionProc ) ;
-wxWidgetImplType* wxWidgetImpl::CreateUserPane( wxWindowMac* wxpeer, wxWindowMac* parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
- long style, long extraStyle)
+wxWidgetImplType* wxWidgetImpl::CreateUserPane( wxWindowMac* wxpeer,
+ wxWindowMac* WXUNUSED(parent),
+ wxWindowID WXUNUSED(id),
+ const wxPoint& pos,
+ const wxSize& size,
+ long WXUNUSED(style),
+ long WXUNUSED(extraStyle))
{
OSStatus err = noErr;
Rect bounds = wxMacGetBoundsForControl( wxpeer , pos , size ) ;
- wxMacControl* c = new wxMacControl(wxpeer) ;
+ wxMacControl* c = new wxMacControl(wxpeer, false, true) ;
UInt32 features = 0
| kControlSupportsEmbedding
| kControlSupportsLiveFeedback
Init();
}
-wxMacControl::wxMacControl(wxWindowMac* peer , bool isRootControl ) :
- wxWidgetImpl( peer, isRootControl )
+wxMacControl::wxMacControl(wxWindowMac* peer , bool isRootControl, bool isUserPane ) :
+ wxWidgetImpl( peer, isRootControl, isUserPane )
{
Init();
}
void wxMacControl::Embed( wxWidgetImpl *parent )
{
- HIViewAddSubview(parent->GetWXWidget(), m_controlRef);
+ HIViewAddSubview((ControlRef)parent->GetWXWidget(), m_controlRef);
}
void wxMacControl::SetNeedsDisplay( const wxRect* rect )
{
verify_noerr( HIViewSetZOrder( m_controlRef, kHIViewZOrderAbove, NULL ) );
}
-
+
void wxMacControl::Lower()
{
verify_noerr( HIViewSetZOrder( m_controlRef, kHIViewZOrderBelow, NULL ) );
void wxMacControl::GetContentArea(int &left , int &top , int &width , int &height) const
{
- RgnHandle rgn = NewRgn() ;
+ HIShapeRef rgn = NULL;
Rect content ;
- if ( GetControlRegion( m_controlRef, kControlContentMetaPart , rgn ) == noErr )
- GetRegionBounds( rgn , &content ) ;
+
+ if ( HIViewCopyShape(m_controlRef, kHIViewContentMetaPart, &rgn) == noErr)
+ {
+ CGRect cgrect;
+ HIShapeGetBounds(rgn, &cgrect);
+ content = (Rect){ (short)cgrect.origin.y,
+ (short)cgrect.origin.x,
+ (short)(cgrect.origin.y+cgrect.size.height),
+ (short)(cgrect.origin.x+cgrect.size.width) };
+ CFRelease(rgn);
+ }
else
{
- GetControlBounds( m_controlRef , &content );
+ GetControlBounds(m_controlRef, &content);
content.right -= content.left;
content.left = 0;
content.bottom -= content.top;
content.top = 0;
}
- DisposeRgn( rgn ) ;
left = content.left;
top = content.top;
void wxMacControl::Move(int x, int y, int width, int height)
{
+ UInt32 attr = 0 ;
+ GetWindowAttributes( GetControlOwner(m_controlRef) , &attr ) ;
+
HIRect hir = CGRectMake(x,y,width,height);
+ if ( !(attr & kWindowCompositingAttribute) )
+ {
+ HIRect parent;
+ HIViewGetFrame( HIViewGetSuperview(m_controlRef), &parent );
+ hir.origin.x += parent.origin.x;
+ hir.origin.y += parent.origin.y;
+ }
HIViewSetFrame ( m_controlRef , &hir );
}
GetControlBounds( m_controlRef , &r );
x = r.left;
y = r.top;
+
+ UInt32 attr = 0 ;
+ GetWindowAttributes( GetControlOwner(m_controlRef) , &attr ) ;
+
+ if ( !(attr & kWindowCompositingAttribute) )
+ {
+ HIRect parent;
+ HIViewGetFrame( HIViewGetSuperview(m_controlRef), &parent );
+ x -= (int)parent.origin.x;
+ y -= (int)parent.origin.y;
+ }
+
}
void wxMacControl::GetSize( int &width, int &height ) const
height = r.bottom - r.top;
}
-void wxMacControl::SetControlSize( wxWindowVariant variant )
+void wxMacControl::SetControlSize( wxWindowVariant variant )
{
ControlSize size ;
switch ( variant )
break ;
default:
- wxFAIL_MSG(_T("unexpected window variant"));
+ wxFAIL_MSG(wxT("unexpected window variant"));
break ;
}
if ( err == errCouldntSetFocus )
return false ;
SetUserFocusWindow(GetControlOwner( m_controlRef ) );
-
+
return true;
}
return control == m_controlRef;
}
+void wxMacControl::SetCursor(const wxCursor& cursor)
+{
+ wxWindowMac *mouseWin = 0 ;
+ WindowRef window = GetControlOwner( m_controlRef ) ;
+
+ wxNonOwnedWindow* tlwwx = wxNonOwnedWindow::GetFromWXWindow( (WXWindow) window ) ;
+ if ( tlwwx != NULL )
+ {
+ ControlPartCode part ;
+ ControlRef control ;
+ Point pt ;
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
+ HIPoint hiPoint ;
+ HIGetMousePosition(kHICoordSpaceWindow, window, &hiPoint);
+ pt.h = hiPoint.x;
+ pt.v = hiPoint.y;
+#else
+ GetGlobalMouse( &pt );
+ int x = pt.h;
+ int y = pt.v;
+ tlwwx->ScreenToClient(&x, &y);
+ pt.h = x;
+ pt.v = y;
+#endif
+ control = FindControlUnderMouse( pt , window , &part ) ;
+ if ( control )
+ mouseWin = wxFindWindowFromWXWidget( (WXWidget) control ) ;
+ }
+
+ if ( mouseWin == tlwwx && !wxIsBusy() )
+ cursor.MacInstall() ;
+}
+
+void wxMacControl::CaptureMouse()
+{
+}
+
+void wxMacControl::ReleaseMouse()
+{
+}
+
//
// subclass specifics
//
return ::GetControl32BitValue( m_controlRef );
}
-SInt32 wxMacControl::GetMaximum() const
+wxInt32 wxMacControl::GetMaximum() const
{
return ::GetControl32BitMaximum( m_controlRef );
}
-/*
wxInt32 wxMacControl::GetMinimum() const
{
return ::GetControl32BitMinimum( m_controlRef );
}
-*/
void wxMacControl::SetValue( wxInt32 v )
{
flush = kHIThemeTextHorizontalFlushCenter;
else if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_RIGHT )
flush = kHIThemeTextHorizontalFlushRight;
- HIViewSetTextFont( m_controlRef , part , (CTFontRef) font.MacGetCTFont() );
+ HIViewSetTextFont( m_controlRef , part , (CTFontRef) font.OSXGetCTFont() );
HIViewSetTextHorizontalFlush( m_controlRef, part, flush );
if ( foreground != *wxBLACK || ignoreBlack == false )
{
fontStyle.font = font.MacGetFontNum();
fontStyle.style = font.MacGetFontStyle();
- fontStyle.size = font.MacGetFontSize();
+ fontStyle.size = font.GetPointSize();
fontStyle.flags = kControlUseFontMask | kControlUseFaceMask | kControlUseSizeMask;
}
// HITextViewSetBackgroundColor( m_textView , color );
}
+bool wxMacControl::SetBackgroundStyle(wxBackgroundStyle style)
+{
+ if ( style != wxBG_STYLE_PAINT )
+ {
+ OSStatus err = HIViewChangeFeatures(m_controlRef , 0 , kHIViewIsOpaque);
+ verify_noerr( err );
+ }
+ else
+ {
+ OSStatus err = HIViewChangeFeatures(m_controlRef , kHIViewIsOpaque , 0);
+ verify_noerr( err );
+ }
+
+ return true ;
+}
+
void wxMacControl::SetRange( SInt32 minimum , SInt32 maximum )
{
::SetControl32BitMinimum( m_controlRef , minimum );
void wxMacControl::SetDrawingEnabled( bool enable )
{
- HIViewSetDrawingEnabled( m_controlRef , enable );
+ if ( enable )
+ {
+ HIViewSetDrawingEnabled( m_controlRef , true );
+ HIViewSetNeedsDisplay( m_controlRef, true);
+ }
+ else
+ {
+ HIViewSetDrawingEnabled( m_controlRef , false );
+ }
}
void wxMacControl::GetRectInWindowCoords( Rect *r )
GetControlFeatures( m_controlRef , features );
}
-OSStatus wxMacControl::GetRegion( ControlPartCode partCode , RgnHandle region )
-{
- OSStatus err = GetControlRegion( m_controlRef , partCode , region );
- return err;
-}
-
void wxMacControl::PulseGauge()
{
}
return NULL;
}
+wxBitmap wxMacControl::GetBitmap() const
+{
+ return wxNullBitmap;
+}
+
void wxMacControl::SetBitmap( const wxBitmap& WXUNUSED(bmp) )
{
// implemented in the respective subclasses
}
-void wxMacControl::SetScrollThumb( wxInt32 WXUNUSED(pos), wxInt32 WXUNUSED(viewsize) )
+void wxMacControl::SetBitmapPosition( wxDirection WXUNUSED(dir) )
{
- // implemented in respective subclass
+ // implemented in the same subclasses that implement SetBitmap()
}
-void wxMacControl::AddSubWidget( wxWidgetImpl* widget )
+void wxMacControl::SetScrollThumb( wxInt32 WXUNUSED(pos), wxInt32 WXUNUSED(viewsize) )
{
- ControlRef container = (ControlRef) GetWXWidget() ;
- wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
- ::EmbedControl( (ControlRef) widget->GetWXWidget() , container ) ;
+ // implemented in respective subclass
}
//
// Control Factory
-wxWidgetImplType* wxWidgetImpl::CreateContentView( wxNonOwnedWindow* now )
+wxWidgetImplType* wxWidgetImpl::CreateContentView( wxNonOwnedWindow* now )
{
// There is a bug in 10.2.X for ::GetRootControl returning the window view instead of
// the content view, so we have to retrieve it explicitly
-
+
wxMacControl* contentview = new wxMacControl(now , true /*isRootControl*/);
HIViewFindByID( HIViewGetRoot( (WindowRef) now->GetWXWindow() ) , kHIViewWindowContentID ,
contentview->GetControlRefAddr() ) ;
}
// the root control level handler
- contentview->InstallEventHandler() ;
+ if ( !now->IsNativeWindowWrapper() )
+ contentview->InstallEventHandler() ;
+
return contentview;
}