#include "wx/wxprec.h"
-#include <Cocoa/Cocoa.h>
+#ifndef WX_PRECOMP
+ #include "wx/nonownedwnd.h"
+ #include "wx/log.h"
+#endif
#ifdef __WXMAC__
#include "wx/osx/private.h"
#endif
+#if wxUSE_CARET
+ #include "wx/caret.h"
+#endif
+
NSRect wxOSXGetFrameForControl( wxWindowMac* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin )
{
int x, y, w, h ;
@interface wxNSView : NSView
{
- wxWidgetImpl* impl;
+ WXCOCOAIMPL_COMMON_MEMBERS
}
- (void)drawRect: (NSRect) rect;
--(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)handleMouseEvent:(NSEvent *)event;
+WXCOCOAIMPL_COMMON_INTERFACE
-- (void)setImplementation: (wxWidgetImpl *) theImplementation;
-- (wxWidgetImpl*) implementation;
-- (BOOL) isFlipped;
-- (BOOL) becomeFirstResponder;
-- (BOOL) resignFirstResponder;
+- (BOOL) canBecomeKeyView;
@end // wxNSView
+@interface NSView(PossibleMethods)
+- (void)setImplementation:(wxWidgetCocoaImpl *)theImplementation;
+- (void)setTitle:(NSString *)aString;
+- (void)setStringValue:(NSString *)aString;
+- (void)setIntValue:(int)anInt;
+- (void)setFloatValue:(float)aFloat;
+- (void)setDoubleValue:(double)aDouble;
+
+- (double)minValue;
+- (double)maxValue;
+- (void)setMinValue:(double)aDouble;
+- (void)setMaxValue:(double)aDouble;
+
+- (void)sizeToFit;
+
+- (BOOL)isEnabled;
+- (void)setEnabled:(BOOL)flag;
+
+- (void)setImage:(NSImage *)image;
+- (void)setControlSize:(NSControlSize)size;
+
+- (id)contentView;
+@end
+
+long wxOSXTranslateCocoaKey( int unichar )
+{
+ long retval = unichar;
+ switch( unichar )
+ {
+ case NSUpArrowFunctionKey :
+ retval = WXK_UP;
+ break;
+ case NSDownArrowFunctionKey :
+ retval = WXK_DOWN;
+ break;
+ case NSLeftArrowFunctionKey :
+ retval = WXK_LEFT;
+ break;
+ case NSRightArrowFunctionKey :
+ retval = WXK_RIGHT;
+ break;
+ case NSInsertFunctionKey :
+ retval = WXK_INSERT;
+ break;
+ case NSDeleteFunctionKey :
+ retval = WXK_DELETE;
+ break;
+ case NSHomeFunctionKey :
+ retval = WXK_HOME;
+ break;
+// case NSBeginFunctionKey :
+// retval = WXK_BEGIN;
+// break;
+ case NSEndFunctionKey :
+ retval = WXK_END;
+ break;
+ case NSPageUpFunctionKey :
+ retval = WXK_PAGEUP;
+ break;
+ case NSPageDownFunctionKey :
+ retval = WXK_PAGEDOWN;
+ break;
+ case NSHelpFunctionKey :
+ retval = WXK_HELP;
+ break;
+
+ default :
+ if ( unichar >= NSF1FunctionKey && unichar >= NSF24FunctionKey )
+ retval = WXK_F1 + (unichar - NSF1FunctionKey );
+ break;
+ }
+ return retval;
+}
+
+void SetupKeyEvent( wxKeyEvent &wxevent , NSEvent * nsEvent )
+{
+ UInt32 modifiers = [nsEvent modifierFlags] ;
+ int eventType = [nsEvent type];
+
+ wxevent.m_shiftDown = modifiers & NSShiftKeyMask;
+ wxevent.m_controlDown = modifiers & NSControlKeyMask;
+ wxevent.m_altDown = modifiers & NSAlternateKeyMask;
+ wxevent.m_metaDown = modifiers & NSCommandKeyMask;
+
+ wxevent.m_rawCode = [nsEvent keyCode];
+ wxevent.m_rawFlags = modifiers;
+
+ wxevent.SetTimestamp( [nsEvent timestamp] * 1000.0 ) ;
+ switch (eventType)
+ {
+ case NSKeyDown :
+ wxevent.SetEventType( wxEVT_KEY_DOWN ) ;
+ break;
+ case NSKeyUp :
+ wxevent.SetEventType( wxEVT_KEY_UP ) ;
+ break;
+ case NSFlagsChanged :
+ // setup common code here
+ break;
+ default :
+ break ;
+ }
+
+ wxString chars;
+ if ( eventType != NSFlagsChanged )
+ {
+ NSString* nschars = [nsEvent characters];
+ if ( nschars )
+ {
+ wxCFStringRef cfchars((CFStringRef)[nschars retain]);
+ chars = cfchars.AsString();
+ }
+ }
+
+ int unichar = chars.Length() > 0 ? chars[0] : 0;
+ long keyval = wxOSXTranslateCocoaKey(unichar) ;
+ if ( keyval == unichar && ( wxevent.GetEventType() == wxEVT_KEY_UP || wxevent.GetEventType() == wxEVT_KEY_DOWN ) )
+ keyval = wxToupper( keyval ) ;
+
+#if wxUSE_UNICODE
+ wxevent.m_uniChar = unichar;
+#endif
+ wxevent.m_keyCode = keyval;
+}
+
+UInt32 g_lastButton = 0 ;
+bool g_lastButtonWasFakeRight = false ;
+
void SetupMouseEvent( wxMouseEvent &wxevent , NSEvent * nsEvent )
{
UInt32 modifiers = [nsEvent modifierFlags] ;
// these parameters are not given for all events
UInt32 button = [nsEvent buttonNumber];
UInt32 clickCount = [nsEvent clickCount];
- UInt32 mouseChord = 0; // TODO does this exist for cocoa
wxevent.m_x = screenMouseLocation.x;
wxevent.m_y = screenMouseLocation.y;
wxevent.m_metaDown = modifiers & NSCommandKeyMask;
wxevent.m_clickCount = clickCount;
wxevent.SetTimestamp( [nsEvent timestamp] * 1000.0 ) ;
-/*
+
+ 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
if(mouseChord & 4U)
wxevent.m_middleDown = true ;
-*/
// translate into wx types
- int eventType = [nsEvent type];
switch (eventType)
{
case NSLeftMouseDown :
wxRegion updateRgn;
const NSRect *rects;
- int count ;
+ NSInteger count;
[self getRectsBeingDrawn:&rects count:&count];
for ( int i = 0 ; i < count ; ++i )
}
}
--(void)mouseDown:(NSEvent *)event
-{
- [self handleMouseEvent:event];
-}
-
--(void)rightMouseDown:(NSEvent *)event
-{
- [self handleMouseEvent:event];
-}
-
--(void)otherMouseDown:(NSEvent *)event
-{
- [self handleMouseEvent:event];
-}
-
--(void)mouseUp:(NSEvent *)event
-{
- [self handleMouseEvent:event];
-}
+WXCOCOAIMPL_COMMON_IMPLEMENTATION
--(void)rightMouseUp:(NSEvent *)event
-{
- [self handleMouseEvent:event];
-}
-
--(void)otherMouseUp:(NSEvent *)event
-{
- [self handleMouseEvent:event];
-}
-
--(void)handleMouseEvent:(NSEvent *)event
-{
- NSPoint clickLocation;
- clickLocation = [self convertPoint:[event locationInWindow] fromView:nil];
- wxPoint pt = wxFromNSPoint( self, clickLocation );
- wxMouseEvent wxevent(wxEVT_LEFT_DOWN);
- SetupMouseEvent( wxevent , event ) ;
- wxevent.m_x = pt.x;
- wxevent.m_y = pt.y;
- impl->GetWXPeer()->HandleWindowEvent(wxevent);
-}
-
-- (void)setImplementation: (wxWidgetImpl *) theImplementation
-{
- impl = theImplementation;
-}
-
-- (wxWidgetImpl*) implementation
-{
- return impl;
-}
-
-- (BOOL) isFlipped
+- (BOOL) canBecomeKeyView
{
return YES;
}
-- (BOOL) becomeFirstResponder
-{
- BOOL r = [super becomeFirstResponder];
- if ( r )
- {
- }
- return r;
-}
-
-- (BOOL) resignFirstResponder
-{
- BOOL r = [super resignFirstResponder];
- if ( r )
- {
- }
- return r;
-}
-
-
@end // wxNSView
IMPLEMENT_DYNAMIC_CLASS( wxWidgetCocoaImpl , wxWidgetImpl )
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)
{
+ wxWindowMac* parent = GetWXPeer()->GetParent();
+ // under Cocoa we might have a contentView in the wxParent to which we have to
+ // adjust the coordinates
+ if (parent)
+ {
+ wxPoint pt(parent->GetClientAreaOrigin());
+ x -= pt.x;
+ y -= pt.y;
+ }
NSRect r = wxToNSRect( [m_osxView superview], wxRect(x,y,width, height) );
[m_osxView setFrame:r];
}
void wxWidgetCocoaImpl::GetContentArea( int&left, int &top, int &width, int &height ) const
{
- left = top = 0;
- GetSize( width, height );
+ if ( [m_osxView respondsToSelector:@selector(contentView) ] )
+ {
+ NSView* cv = [m_osxView contentView];
+
+ NSRect bounds = [m_osxView bounds];
+ NSRect rect = [cv frame];
+
+ int y = rect.origin.y;
+ int x = rect.origin.x;
+ if ( ![ m_osxView isFlipped ] )
+ y = bounds.size.height - (rect.origin.y + rect.size.height);
+ left = x;
+ top = y;
+ width = rect.size.width;
+ height = rect.size.height;
+ }
+ else
+ {
+ left = top = 0;
+ GetSize( width, height );
+ }
}
void wxWidgetCocoaImpl::SetNeedsDisplay( const wxRect* where )
}
}
+wxInt32 wxWidgetCocoaImpl::GetMinimum() const
+{
+ if ( [m_osxView respondsToSelector:@selector(getMinValue:)] )
+ {
+ return [m_osxView minValue];
+ }
+ return 0;
+}
+
+wxInt32 wxWidgetCocoaImpl::GetMaximum() const
+{
+ if ( [m_osxView respondsToSelector:@selector(getMaxValue:)] )
+ {
+ return [m_osxView maxValue];
+ }
+ return 0;
+}
+
void wxWidgetCocoaImpl::SetBitmap( const wxBitmap& bitmap )
{
if ( [m_osxView respondsToSelector:@selector(setImage:)] )
[m_osxView setControlSize:size];
}
+void wxWidgetCocoaImpl::SetFont(wxFont const&, wxColour const&, long, bool)
+{
+ // TODO
+}
+
+void wxWidgetCocoaImpl::InstallEventHandler( WXWidget control )
+{
+}
+
+bool wxWidgetCocoaImpl::DoHandleKeyEvent(NSEvent *event)
+{
+ wxKeyEvent wxevent(wxEVT_KEY_DOWN);
+ SetupKeyEvent( wxevent, event );
+
+ return GetWXPeer()->OSXHandleKeyEvent(wxevent);
+}
+
+bool wxWidgetCocoaImpl::DoHandleMouseEvent(NSEvent *event)
+{
+ NSPoint clickLocation;
+ clickLocation = [m_osxView convertPoint:[event locationInWindow] fromView:nil];
+ wxPoint pt = wxFromNSPoint( m_osxView, clickLocation );
+ wxMouseEvent wxevent(wxEVT_LEFT_DOWN);
+ SetupMouseEvent( wxevent , event ) ;
+ wxevent.m_x = pt.x;
+ wxevent.m_y = pt.y;
+
+ return GetWXPeer()->HandleWindowEvent(wxevent);
+}
+
+void wxWidgetCocoaImpl::DoNotifyFocusEvent(bool receivedFocus)
+{
+ wxWindow* thisWindow = GetWXPeer();
+ if ( thisWindow->MacGetTopLevelWindow() && NeedsFocusRect() )
+ {
+ thisWindow->MacInvalidateBorders();
+ }
+
+ if ( receivedFocus )
+ {
+ wxLogTrace(_T("Focus"), _T("focus set(%p)"), static_cast<void*>(thisWindow));
+ wxChildFocusEvent eventFocus((wxWindow*)thisWindow);
+ thisWindow->HandleWindowEvent(eventFocus);
+
+#if wxUSE_CARET
+ if ( thisWindow->GetCaret() )
+ thisWindow->GetCaret()->OnSetFocus();
+#endif
+
+ wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId());
+ event.SetEventObject(thisWindow);
+ // TODO how to find out the targetFocusWindow ?
+ // event.SetWindow(targetFocusWindow);
+ thisWindow->HandleWindowEvent(event) ;
+ }
+ else // !receivedFocuss
+ {
+#if wxUSE_CARET
+ if ( thisWindow->GetCaret() )
+ thisWindow->GetCaret()->OnKillFocus();
+#endif
+
+ wxLogTrace(_T("Focus"), _T("focus lost(%p)"), static_cast<void*>(thisWindow));
+
+ wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId());
+ event.SetEventObject(thisWindow);
+ // TODO how to find out the targetFocusWindow ?
+ // event.SetWindow(targetFocusWindow);
+ thisWindow->HandleWindowEvent(event) ;
+ }
+}
+
+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
//