]> git.saurik.com Git - wxWidgets.git/blobdiff - src/osx/cocoa/window.mm
compilation fix for old SDKs (VC6...) which don't define HDM_SETBITMAPMARGIN/Header_S...
[wxWidgets.git] / src / osx / cocoa / window.mm
index 9345dc988c0a37e38d151bf0421098ba7cc87c3b..eca008e83bd647bd76a2d09d090e6b24eb1d0a04 100644 (file)
 
 #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 ;
@@ -30,27 +37,136 @@ NSRect wxOSXGetFrameForControl( wxWindowMac* window , const wxPoint& pos , const
 
 @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;
+
+- (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(unsigned short code, int unichar )
+{
+    long retval = code;
+    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;
+
+    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;
+    
+#if wxUSE_UNICODE
+    wxevent.m_uniChar = unichar;
+#endif
+    wxevent.m_keyCode = wxOSXTranslateCocoaKey( [nsEvent keyCode], unichar ) ;
+//    wxevent.m_rawCode = keymessage;
+    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 ;
+    }
+}
+
 void SetupMouseEvent( wxMouseEvent &wxevent , NSEvent * nsEvent )
 {
     UInt32 modifiers = [nsEvent modifierFlags] ;
@@ -59,7 +175,6 @@ void SetupMouseEvent( wxMouseEvent &wxevent , NSEvent * nsEvent )
     // 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;
@@ -70,6 +185,7 @@ void SetupMouseEvent( wxMouseEvent &wxevent , NSEvent * nsEvent )
     wxevent.m_clickCount = clickCount;
     wxevent.SetTimestamp( [nsEvent timestamp] * 1000.0 ) ;
 /*
+    UInt32 mouseChord = 0; // TODO does this exist for cocoa
     // a control click is interpreted as a right click
     bool thisButtonIsFakeRight = false ;
     if ( button == kEventMouseButtonPrimary && (modifiers & controlKey) )
@@ -222,7 +338,7 @@ void SetupMouseEvent( wxMouseEvent &wxevent , NSEvent * nsEvent )
         
         wxRegion updateRgn;
         const NSRect *rects;
-        int count ;
+        NSInteger count;
 
         [self getRectsBeingDrawn:&rects count:&count];
         for ( int i = 0 ; i < count ; ++i )
@@ -243,82 +359,13 @@ void SetupMouseEvent( wxMouseEvent &wxevent , NSEvent * nsEvent )
     }
 }
 
--(void)mouseDown:(NSEvent *)event 
-{
-    [self handleMouseEvent:event];
-}
+WXCOCOAIMPL_COMMON_IMPLEMENTATION
 
--(void)rightMouseDown:(NSEvent *)event 
-{
-    [self handleMouseEvent:event];
-}
-
--(void)otherMouseDown:(NSEvent *)event 
-{
-    [self handleMouseEvent:event];
-}
-
--(void)mouseUp:(NSEvent *)event 
-{
-    [self handleMouseEvent:event];
-}
-
--(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 )
@@ -374,6 +421,15 @@ void wxWidgetCocoaImpl::ScrollRect( const wxRect *rect, int dx, int dy )
 
 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];
 }
@@ -394,8 +450,27 @@ void wxWidgetCocoaImpl::GetSize( int &width, int &height ) const
 
 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 )
@@ -532,12 +607,15 @@ void wxWidgetCocoaImpl::GetBestRect( wxRect *r ) const
 
 bool wxWidgetCocoaImpl::IsEnabled() const
 {
-    return [m_osxView enable];
+    if ( [m_osxView respondsToSelector:@selector(isEnabled) ] )
+        return [m_osxView isEnabled];
+    return true;
 }
 
 void wxWidgetCocoaImpl::Enable( bool enable )
 {
-    [m_osxView setEnabled:enable];
+    if ( [m_osxView respondsToSelector:@selector(setEnabled:) ] )
+        [m_osxView setEnabled:enable];
 }
 
 void wxWidgetCocoaImpl::PulseGauge()
@@ -548,6 +626,108 @@ void wxWidgetCocoaImpl::SetScrollThumb( wxInt32 val, wxInt32 view )
 {
 }
 
+void wxWidgetCocoaImpl::SetControlSize( wxWindowVariant variant ) 
+{
+    NSControlSize size = NSRegularControlSize;
+    
+    switch ( variant )
+    {
+        case wxWINDOW_VARIANT_NORMAL :
+            size = NSRegularControlSize;
+            break ;
+
+        case wxWINDOW_VARIANT_SMALL :
+            size = NSSmallControlSize;
+            break ;
+
+        case wxWINDOW_VARIANT_MINI :
+            size = NSMiniControlSize;
+            break ;
+
+        case wxWINDOW_VARIANT_LARGE :
+            size = NSRegularControlSize;
+            break ;
+
+        default:
+            wxFAIL_MSG(_T("unexpected window variant"));
+            break ;
+    }
+    if ( [m_osxView respondsToSelector:@selector(setControlSize:)] )
+        [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()->HandleWindowEvent(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) ;
+    }
+}
+
+
 //
 // Factory methods
 //