From 54f11060867c4c97ebbe7954353f5c311262fc4b Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Sun, 18 Jan 2009 16:10:46 +0000 Subject: [PATCH] mouse and cursor additions for cocoa, see #10361 git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58198 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/osx/carbon/private.h | 4 ++ include/wx/osx/cocoa/private.h | 56 ++++++++++++++++++-- include/wx/osx/core/private.h | 4 ++ src/osx/carbon/window.cpp | 41 +++++++++++++++ src/osx/cocoa/nonownedwnd.mm | 24 ++++----- src/osx/cocoa/scrolbar.mm | 4 +- src/osx/cocoa/utils.mm | 6 ++- src/osx/cocoa/window.mm | 92 ++++++++++++++++++++++++++++----- src/osx/window_osx.cpp | 40 ++++---------- 9 files changed, 208 insertions(+), 63 deletions(-) diff --git a/include/wx/osx/carbon/private.h b/include/wx/osx/carbon/private.h index d0b3ca3f08..11d00c8ccc 100644 --- a/include/wx/osx/carbon/private.h +++ b/include/wx/osx/carbon/private.h @@ -329,6 +329,10 @@ public : void PerformClick(); void SetLabel( const wxString& title, wxFontEncoding encoding ); + void SetCursor( const wxCursor & cursor ); + void CaptureMouse(); + void ReleaseMouse(); + wxInt32 GetValue() const; void SetValue( wxInt32 v ); void SetBitmap( const wxBitmap& bitmap ); diff --git a/include/wx/osx/cocoa/private.h b/include/wx/osx/cocoa/private.h index d998d8950f..d1b4c83962 100644 --- a/include/wx/osx/cocoa/private.h +++ b/include/wx/osx/cocoa/private.h @@ -100,6 +100,10 @@ public : void PerformClick(); void SetLabel(const wxString& title, wxFontEncoding encoding); + void SetCursor( const wxCursor & cursor ); + void CaptureMouse(); + void ReleaseMouse(); + wxInt32 GetValue() const; void SetValue( wxInt32 v ); void SetBitmap( const wxBitmap& bitmap ); @@ -201,11 +205,18 @@ protected : // later to be done using injection in method table #define WXCOCOAIMPL_COMMON_EVENTS_INTERFACE -(void)mouseDown:(NSEvent *)event ;\ - -(void)rightMouseDown:(NSEvent *)event ;\ - -(void)otherMouseDown:(NSEvent *)event ;\ - -(void)mouseUp:(NSEvent *)event ;\ - -(void)rightMouseUp:(NSEvent *)event ;\ - -(void)otherMouseUp:(NSEvent *)event ;\ + - (void)rightMouseDown:(NSEvent *)event ;\ + - (void)otherMouseDown:(NSEvent *)event ;\ + - (void)mouseUp:(NSEvent *)event ;\ + - (void)rightMouseUp:(NSEvent *)event ;\ + - (void)otherMouseUp:(NSEvent *)event ;\ + - (void)mouseMoved:(NSEvent *)event;\ + - (void)mouseDragged:(NSEvent *)event;\ + - (void)rightMouseDragged:(NSEvent *)event;\ + - (void)otherMouseDragged:(NSEvent *)event;\ + - (void)scrollWheel:(NSEvent *)theEvent;\ + - (void)mouseEntered:(NSEvent *)event;\ + - (void)mouseExited:(NSEvent *)event;\ - (void)keyDown:(NSEvent *)event;\ - (void)keyUp:(NSEvent *)event;\ - (void)flagsChanged:(NSEvent *)event;\ @@ -242,6 +253,41 @@ protected : if ( !impl->DoHandleMouseEvent(event) )\ [super otherMouseUp:event];\ }\ + -(void)mouseMoved:(NSEvent *)event\ + {\ + if ( !impl->DoHandleMouseEvent(event) )\ + [super mouseMoved:event];\ + }\ + -(void)mouseDragged:(NSEvent *)event\ + {\ + if ( !impl->DoHandleMouseEvent(event) )\ + [super mouseDragged:event];\ + }\ + -(void)rightMouseDragged:(NSEvent *)event\ + {\ + if ( !impl->DoHandleMouseEvent(event) )\ + [super rightMouseDragged:event];\ + }\ + -(void)otherMouseDragged:(NSEvent *)event\ + {\ + if ( !impl->DoHandleMouseEvent(event) )\ + [super otherMouseDragged:event];\ + }\ + -(void)scrollWheel:(NSEvent *)event\ + {\ + if ( !impl->DoHandleMouseEvent(event) )\ + [super scrollWheel:event];\ + }\ + -(void)mouseEntered:(NSEvent *)event\ + {\ + if ( !impl->DoHandleMouseEvent(event) )\ + [super mouseEntered:event];\ + }\ + -(void)mouseExited:(NSEvent *)event\ + {\ + if ( !impl->DoHandleMouseEvent(event) )\ + [super mouseExited:event];\ + }\ -(void)keyDown:(NSEvent *)event\ {\ if ( !impl->DoHandleKeyEvent(event) )\ diff --git a/include/wx/osx/core/private.h b/include/wx/osx/core/private.h index d16cbfa3fc..7a70f84fcf 100644 --- a/include/wx/osx/core/private.h +++ b/include/wx/osx/core/private.h @@ -220,6 +220,10 @@ public : virtual void PerformClick() = 0; virtual void SetLabel( const wxString& title, wxFontEncoding encoding ) = 0; + virtual void SetCursor( const wxCursor & cursor ) = 0; + virtual void CaptureMouse() = 0; + virtual void ReleaseMouse() = 0; + virtual wxInt32 GetValue() const = 0; virtual void SetValue( wxInt32 v ) = 0; virtual void SetBitmap( const wxBitmap& bitmap ) = 0; diff --git a/src/osx/carbon/window.cpp b/src/osx/carbon/window.cpp index 1f760a8ef0..392c061792 100644 --- a/src/osx/carbon/window.cpp +++ b/src/osx/carbon/window.cpp @@ -1038,6 +1038,47 @@ bool wxMacControl::HasFocus() const 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 // diff --git a/src/osx/cocoa/nonownedwnd.mm b/src/osx/cocoa/nonownedwnd.mm index 20a01d1834..f442eef85a 100644 --- a/src/osx/cocoa/nonownedwnd.mm +++ b/src/osx/cocoa/nonownedwnd.mm @@ -426,7 +426,8 @@ bool wxNonOwnedWindowCocoaImpl::CanSetTransparent() void wxNonOwnedWindowCocoaImpl::MoveWindow(int x, int y, int width, int height) { NSRect r = wxToNSRect( NULL, wxRect(x,y,width, height) ); - [m_macWindow setFrame:r display:YES]; + // do not trigger refreshes upon invisible and possible partly created objects + [m_macWindow setFrame:r display:GetWXPeer()->IsShownOnScreen()]; } void wxNonOwnedWindowCocoaImpl::GetPosition( int &x, int &y ) const @@ -534,24 +535,23 @@ void wxNonOwnedWindowCocoaImpl::RequestUserAttention(int WXUNUSED(flags)) void wxNonOwnedWindowCocoaImpl::ScreenToWindow( int *x, int *y ) { wxPoint p((x ? *x : 0), (y ? *y : 0) ); - /* NSPoint nspt = wxToNSPoint( NULL, p ); - - nspt = [[m_macWindow contentView] convertPoint:p toV:nil]; - p = wxFromNSPoint( - */ + nspt = [m_macWindow convertScreenToBase:nspt]; + nspt = [[m_macWindow contentView] convertPoint:nspt fromView:nil]; + p = wxFromNSPoint([m_macWindow contentView], nspt); if ( x ) - *x = p.x; + *x = p.x; if ( y ) *y = p.y; } void wxNonOwnedWindowCocoaImpl::WindowToScreen( int *x, int *y ) { - wxPoint p( (x ? *x : 0), (y ? *y : 0) ); - /* - p = [m_macWindow convertPoint:p toWindow:nil]; - */ + wxPoint p((x ? *x : 0), (y ? *y : 0) ); + NSPoint nspt = wxToNSPoint( [m_macWindow contentView], p ); + nspt = [[m_macWindow contentView] convertPoint:nspt toView:nil]; + nspt = [m_macWindow convertBaseToScreen:nspt]; + p = wxFromNSPoint( NULL, nspt); if ( x ) *x = p.x; if ( y ) @@ -564,4 +564,4 @@ wxNonOwnedWindowImpl* wxNonOwnedWindowImpl::CreateNonOwnedWindow( wxNonOwnedWind wxNonOwnedWindowImpl* now = new wxNonOwnedWindowCocoaImpl( wxpeer ); now->Create( parent, pos, size, style , extraStyle, name ); return now; -} \ No newline at end of file +} diff --git a/src/osx/cocoa/scrolbar.mm b/src/osx/cocoa/scrolbar.mm index ba5a6f1a57..804c5df533 100644 --- a/src/osx/cocoa/scrolbar.mm +++ b/src/osx/cocoa/scrolbar.mm @@ -62,11 +62,12 @@ class wxOSXScrollBarCocoaImpl : public wxWidgetCocoaImpl public : wxOSXScrollBarCocoaImpl( wxWindowMac* peer, WXWidget w) : wxWidgetCocoaImpl( peer, w ) { + m_maximum = 1; } void SetMaximum(wxInt32 v) { - m_maximum = v; + m_maximum = (v == 0) ? 1 : v; } void SetScrollThumb( wxInt32 value, wxInt32 thumbSize ) @@ -102,5 +103,6 @@ wxWidgetImplType* wxWidgetImpl::CreateScrollBar( wxWindowMac* wxpeer, wxWidgetCocoaImpl* c = new wxOSXScrollBarCocoaImpl( wxpeer, v ); [v setImplementation:c]; + [v setEnabled:YES]; return c; } diff --git a/src/osx/cocoa/utils.mm b/src/osx/cocoa/utils.mm index c60da58658..2bd4e81428 100644 --- a/src/osx/cocoa/utils.mm +++ b/src/osx/cocoa/utils.mm @@ -177,6 +177,10 @@ void wxClientDisplayRect(int *x, int *y, int *width, int *height) void wxGetMousePosition( int* x, int* y ) { wxPoint pt = wxFromNSPoint(NULL, [NSEvent mouseLocation]); + if ( x ) + *x = pt.x; + if ( y ) + *y = pt.y; }; wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer) @@ -267,6 +271,4 @@ wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const #endif // wxUSE_GUI - - #endif // wxOSX_USE_COCOA \ No newline at end of file diff --git a/src/osx/cocoa/window.mm b/src/osx/cocoa/window.mm index eca008e83b..9c03ed54fe 100644 --- a/src/osx/cocoa/window.mm +++ b/src/osx/cocoa/window.mm @@ -41,6 +41,8 @@ NSRect wxOSXGetFrameForControl( wxWindowMac* window , const wxPoint& pos , const } - (void)drawRect: (NSRect) rect; +// TODO should the be moved to COMMON ? +- (void)resetCursorRects; WXCOCOAIMPL_COMMON_INTERFACE @@ -167,6 +169,9 @@ void SetupKeyEvent( wxKeyEvent &wxevent , NSEvent * nsEvent ) } } +UInt32 g_lastButton = 0 ; +bool g_lastButtonWasFakeRight = false ; + void SetupMouseEvent( wxMouseEvent &wxevent , NSEvent * nsEvent ) { UInt32 modifiers = [nsEvent modifierFlags] ; @@ -184,34 +189,56 @@ void SetupMouseEvent( wxMouseEvent &wxevent , NSEvent * nsEvent ) wxevent.m_metaDown = modifiers & NSCommandKeyMask; wxevent.m_clickCount = clickCount; wxevent.SetTimestamp( [nsEvent timestamp] * 1000.0 ) ; -/* - UInt32 mouseChord = 0; // TODO does this exist for cocoa + + UInt32 mouseChord = 0; + int eventType = [nsEvent type]; + + switch (eventType) + { + case NSLeftMouseDown : + case NSLeftMouseDragged : + mouseChord = 1U; + break; + case NSRightMouseDown : + case NSRightMouseDragged : + mouseChord = 2U; + break; + case NSOtherMouseDown : + case NSOtherMouseDragged : + mouseChord = 4U; + break; + } + // a control click is interpreted as a right click bool thisButtonIsFakeRight = false ; - if ( button == kEventMouseButtonPrimary && (modifiers & controlKey) ) + if ( button == 0 && (modifiers & NSControlKeyMask) ) { - button = kEventMouseButtonSecondary ; + button = 1 ; thisButtonIsFakeRight = true ; } // otherwise we report double clicks by connecting a left click with a ctrl-left click if ( clickCount > 1 && button != g_lastButton ) clickCount = 1 ; + // we must make sure that our synthetic 'right' button corresponds in // mouse down, moved and mouse up, and does not deliver a right down and left up - - if ( cEvent.GetKind() == kEventMouseDown ) + switch (eventType) { - g_lastButton = button ; - g_lastButtonWasFakeRight = thisButtonIsFakeRight ; - } + case NSLeftMouseDown : + case NSRightMouseDown : + case NSOtherMouseDown : + g_lastButton = button ; + g_lastButtonWasFakeRight = thisButtonIsFakeRight ; + break; + } if ( button == 0 ) { g_lastButton = 0 ; g_lastButtonWasFakeRight = false ; } - else if ( g_lastButton == kEventMouseButtonSecondary && g_lastButtonWasFakeRight ) + else if ( g_lastButton == 1 && g_lastButtonWasFakeRight ) button = g_lastButton ; // Adjust the chord mask to remove the primary button and add the @@ -228,9 +255,7 @@ void SetupMouseEvent( wxMouseEvent &wxevent , NSEvent * nsEvent ) if(mouseChord & 4U) wxevent.m_middleDown = true ; -*/ // translate into wx types - int eventType = [nsEvent type]; switch (eventType) { case NSLeftMouseDown : @@ -359,6 +384,15 @@ void SetupMouseEvent( wxMouseEvent &wxevent , NSEvent * nsEvent ) } } +- (void) resetCursorRects +{ + [super resetCursorRects]; + wxWindow* wxpeer = impl->GetWXPeer(); + NSCursor *cursor = (NSCursor*)wxpeer->GetCursor().GetHCURSOR(); + [self addCursorRect: [self bounds] + cursor: cursor]; +} + WXCOCOAIMPL_COMMON_IMPLEMENTATION - (BOOL) canBecomeKeyView @@ -417,6 +451,18 @@ void wxWidgetCocoaImpl::Lower() void wxWidgetCocoaImpl::ScrollRect( const wxRect *rect, int dx, int dy ) { +#if 1 + SetNeedsDisplay() ; +#else + // We should do something like this, but it wasn't working in 10.4. + if (GetNeedsDisplay() ) + { + SetNeedsDisplay() ; + } + NSRect r = wxToNSRect( [m_osxView superview], *rect ); + NSSize offset = NSMakeSize((float)dx, (float)dy); + [m_osxView scrollRect:r by:offset]; +#endif } void wxWidgetCocoaImpl::Move(int x, int y, int width, int height) @@ -727,6 +773,28 @@ void wxWidgetCocoaImpl::DoNotifyFocusEvent(bool receivedFocus) } } +void wxWidgetCocoaImpl::SetCursor(const wxCursor& cursor) +{ + NSPoint location = [NSEvent mouseLocation]; + location = [[m_osxView window] convertScreenToBase:location]; + NSPoint locationInView = [m_osxView convertPoint:location fromView:nil]; + + if( NSMouseInRect(locationInView, [m_osxView bounds], YES) ) + { + [(NSCursor*)cursor.GetHCURSOR() set]; + } + [[m_osxView window] invalidateCursorRectsForView:m_osxView]; +} + +void wxWidgetCocoaImpl::CaptureMouse() +{ + [[m_osxView window] disableCursorRects]; +} + +void wxWidgetCocoaImpl::ReleaseMouse() +{ + [[m_osxView window] enableCursorRects]; +} // // Factory methods diff --git a/src/osx/window_osx.cpp b/src/osx/window_osx.cpp index ac75853aa4..a2b6b42654 100644 --- a/src/osx/window_osx.cpp +++ b/src/osx/window_osx.cpp @@ -459,6 +459,11 @@ void wxWindowMac::SetFocus() void wxWindowMac::DoCaptureMouse() { wxApp::s_captureWindow = (wxWindow*) this ; +#ifdef wxOSX_USE_COCOA + // TODO do we really need this ? + m_peer->SetFocus() ; +#endif + m_peer->CaptureMouse() ; } wxWindow * wxWindowBase::GetCapture() @@ -469,6 +474,8 @@ wxWindow * wxWindowBase::GetCapture() void wxWindowMac::DoReleaseMouse() { wxApp::s_captureWindow = NULL ; + + m_peer->ReleaseMouse() ; } #if wxUSE_DRAG_AND_DROP @@ -723,37 +730,8 @@ bool wxWindowMac::SetCursor(const wxCursor& cursor) wxASSERT_MSG( m_cursor.Ok(), wxT("cursor must be valid after call to the base version")); - wxWindowMac *mouseWin = 0 ; -#if wxOSX_USE_CARBON - { - wxNonOwnedWindow *tlw = MacGetTopLevelWindow() ; - WindowRef window = (WindowRef) ( tlw ? tlw->GetWXWindow() : 0 ) ; - - 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; - ScreenToClient(&x, &y); - pt.h = x; - pt.v = y; -#endif - control = FindControlUnderMouse( pt , window , &part ) ; - if ( control ) - mouseWin = wxFindWindowFromWXWidget( (WXWidget) control ) ; - - } -#endif - - if ( mouseWin == this && !wxIsBusy() ) - m_cursor.MacInstall() ; + if ( GetPeer() != NULL ) + GetPeer()->SetCursor( m_cursor ); return true ; } -- 2.45.2