| 1 | ///////////////////////////////////////////////////////////////////////////// |
| 2 | // Name: src/cocoa/NSView.mm |
| 3 | // Purpose: wxCocoaNSView |
| 4 | // Author: David Elliott |
| 5 | // Modified by: |
| 6 | // Created: 2003/02/15 |
| 7 | // RCS-ID: $Id$ |
| 8 | // Copyright: (c) 2003 David Elliott |
| 9 | // Licence: wxWindows licence |
| 10 | ///////////////////////////////////////////////////////////////////////////// |
| 11 | |
| 12 | // ============================================================================ |
| 13 | // declarations |
| 14 | // ============================================================================ |
| 15 | |
| 16 | // ---------------------------------------------------------------------------- |
| 17 | // headers |
| 18 | // ---------------------------------------------------------------------------- |
| 19 | |
| 20 | #include "wx/wxprec.h" |
| 21 | #ifndef WX_PRECOMP |
| 22 | #include "wx/window.h" |
| 23 | #endif // WX_PRECOMP |
| 24 | |
| 25 | #include "wx/cocoa/objc/objc_uniquifying.h" |
| 26 | #include "wx/cocoa/NSView.h" |
| 27 | |
| 28 | #import <Foundation/NSNotification.h> |
| 29 | #import <Foundation/NSString.h> |
| 30 | #include "wx/cocoa/objc/NSView.h" |
| 31 | #include "wx/cocoa/ObjcRef.h" |
| 32 | |
| 33 | // ---------------------------------------------------------------------------- |
| 34 | // globals |
| 35 | // ---------------------------------------------------------------------------- |
| 36 | WX_IMPLEMENT_OBJC_INTERFACE_HASHMAP(NSView) |
| 37 | |
| 38 | void wxCocoaNSView::AssociateNSView(WX_NSView cocoaNSView) |
| 39 | { |
| 40 | if(cocoaNSView) |
| 41 | { |
| 42 | sm_cocoaHash.insert(wxCocoaNSViewHash::value_type(cocoaNSView,this)); |
| 43 | [[NSNotificationCenter defaultCenter] addObserver:(id)sm_cocoaObserver selector:@selector(notificationFrameChanged:) name:@"NSViewFrameDidChangeNotification" object:cocoaNSView]; |
| 44 | [cocoaNSView setPostsFrameChangedNotifications: YES]; |
| 45 | } |
| 46 | } |
| 47 | |
| 48 | void wxCocoaNSView::DisassociateNSView(WX_NSView cocoaNSView) |
| 49 | { |
| 50 | if(cocoaNSView) |
| 51 | { |
| 52 | sm_cocoaHash.erase(cocoaNSView); |
| 53 | [[NSNotificationCenter defaultCenter] removeObserver:(id)sm_cocoaObserver name:@"NSViewFrameDidChangeNotification" object:cocoaNSView]; |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | // ============================================================================ |
| 58 | // @class WXNSView |
| 59 | // ============================================================================ |
| 60 | |
| 61 | @implementation WXNSView : NSView |
| 62 | |
| 63 | - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent |
| 64 | { |
| 65 | bool acceptsFirstMouse = false; |
| 66 | wxCocoaNSView *win = wxCocoaNSView::GetFromCocoa(self); |
| 67 | if(!win || !win->Cocoa_acceptsFirstMouse(acceptsFirstMouse, theEvent)) |
| 68 | acceptsFirstMouse = [super acceptsFirstMouse:theEvent]; |
| 69 | return acceptsFirstMouse; |
| 70 | } |
| 71 | |
| 72 | - (void)drawRect: (NSRect)rect |
| 73 | { |
| 74 | wxCocoaNSView *win = wxCocoaNSView::GetFromCocoa(self); |
| 75 | if( !win || !win->Cocoa_drawRect(rect) ) |
| 76 | [super drawRect:rect]; |
| 77 | } |
| 78 | |
| 79 | - (void)mouseDown:(NSEvent *)theEvent |
| 80 | { |
| 81 | wxCocoaNSView *win = wxCocoaNSView::GetFromCocoa(self); |
| 82 | if( !win || !win->Cocoa_mouseDown(theEvent) ) |
| 83 | [super mouseDown:theEvent]; |
| 84 | } |
| 85 | |
| 86 | - (void)mouseDragged:(NSEvent *)theEvent |
| 87 | { |
| 88 | wxCocoaNSView *win = wxCocoaNSView::GetFromCocoa(self); |
| 89 | if( !win || !win->Cocoa_mouseDragged(theEvent) ) |
| 90 | [super mouseDragged:theEvent]; |
| 91 | } |
| 92 | |
| 93 | - (void)mouseUp:(NSEvent *)theEvent |
| 94 | { |
| 95 | wxCocoaNSView *win = wxCocoaNSView::GetFromCocoa(self); |
| 96 | if( !win || !win->Cocoa_mouseUp(theEvent) ) |
| 97 | [super mouseUp:theEvent]; |
| 98 | } |
| 99 | |
| 100 | - (void)mouseMoved:(NSEvent *)theEvent |
| 101 | { |
| 102 | wxCocoaNSView *win = wxCocoaNSView::GetFromCocoa(self); |
| 103 | if( !win || !win->Cocoa_mouseMoved(theEvent) ) |
| 104 | [super mouseMoved:theEvent]; |
| 105 | } |
| 106 | |
| 107 | - (void)mouseEntered:(NSEvent *)theEvent |
| 108 | { |
| 109 | wxCocoaNSView *win = wxCocoaNSView::GetFromCocoa(self); |
| 110 | if( !win || !win->Cocoa_mouseEntered(theEvent) ) |
| 111 | [super mouseEntered:theEvent]; |
| 112 | } |
| 113 | |
| 114 | - (void)mouseExited:(NSEvent *)theEvent |
| 115 | { |
| 116 | wxCocoaNSView *win = wxCocoaNSView::GetFromCocoa(self); |
| 117 | if( !win || !win->Cocoa_mouseExited(theEvent) ) |
| 118 | [super mouseExited:theEvent]; |
| 119 | } |
| 120 | |
| 121 | - (void)rightMouseDown:(NSEvent *)theEvent |
| 122 | { |
| 123 | wxCocoaNSView *win = wxCocoaNSView::GetFromCocoa(self); |
| 124 | if( !win || !win->Cocoa_rightMouseDown(theEvent) ) |
| 125 | [super rightMouseDown:theEvent]; |
| 126 | } |
| 127 | |
| 128 | - (void)rightMouseDragged:(NSEvent *)theEvent |
| 129 | { |
| 130 | wxCocoaNSView *win = wxCocoaNSView::GetFromCocoa(self); |
| 131 | if( !win || !win->Cocoa_rightMouseDragged(theEvent) ) |
| 132 | [super rightMouseDragged:theEvent]; |
| 133 | } |
| 134 | |
| 135 | - (void)rightMouseUp:(NSEvent *)theEvent |
| 136 | { |
| 137 | wxCocoaNSView *win = wxCocoaNSView::GetFromCocoa(self); |
| 138 | if( !win || !win->Cocoa_rightMouseUp(theEvent) ) |
| 139 | [super rightMouseUp:theEvent]; |
| 140 | } |
| 141 | |
| 142 | - (void)otherMouseDown:(NSEvent *)theEvent |
| 143 | { |
| 144 | wxCocoaNSView *win = wxCocoaNSView::GetFromCocoa(self); |
| 145 | if( !win || !win->Cocoa_otherMouseDown(theEvent) ) |
| 146 | [super otherMouseDown:theEvent]; |
| 147 | } |
| 148 | |
| 149 | - (void)otherMouseDragged:(NSEvent *)theEvent |
| 150 | { |
| 151 | wxCocoaNSView *win = wxCocoaNSView::GetFromCocoa(self); |
| 152 | if( !win || !win->Cocoa_otherMouseDragged(theEvent) ) |
| 153 | [super otherMouseDragged:theEvent]; |
| 154 | } |
| 155 | |
| 156 | - (void)otherMouseUp:(NSEvent *)theEvent |
| 157 | { |
| 158 | wxCocoaNSView *win = wxCocoaNSView::GetFromCocoa(self); |
| 159 | if( !win || !win->Cocoa_otherMouseUp(theEvent) ) |
| 160 | [super otherMouseUp:theEvent]; |
| 161 | } |
| 162 | |
| 163 | - (void)resetCursorRects |
| 164 | { |
| 165 | wxCocoaNSView *win = wxCocoaNSView::GetFromCocoa(self); |
| 166 | if( !win || !win->Cocoa_resetCursorRects() ) |
| 167 | [super resetCursorRects]; |
| 168 | } |
| 169 | |
| 170 | - (void)viewDidMoveToWindow |
| 171 | { |
| 172 | wxCocoaNSView *win = wxCocoaNSView::GetFromCocoa(self); |
| 173 | if( !win || !win->Cocoa_viewDidMoveToWindow() ) |
| 174 | [super viewDidMoveToWindow]; |
| 175 | } |
| 176 | |
| 177 | - (void)viewWillMoveToWindow:(NSWindow *)newWindow |
| 178 | { |
| 179 | wxCocoaNSView *win = wxCocoaNSView::GetFromCocoa(self); |
| 180 | if( !win || !win->Cocoa_viewWillMoveToWindow(newWindow) ) |
| 181 | [super viewWillMoveToWindow:newWindow]; |
| 182 | } |
| 183 | |
| 184 | @end // implementation WXNSView |
| 185 | WX_IMPLEMENT_GET_OBJC_CLASS(WXNSView,NSView) |
| 186 | |
| 187 | // ============================================================================ |
| 188 | // @class wxNSViewNotificationObserver |
| 189 | // ============================================================================ |
| 190 | |
| 191 | @interface wxNSViewNotificationObserver : NSObject |
| 192 | { |
| 193 | } |
| 194 | |
| 195 | - (void)notificationFrameChanged: (NSNotification *)notification; |
| 196 | - (void)synthesizeMouseMovedForView: (NSView *)theView; |
| 197 | @end // interface wxNSViewNotificationObserver |
| 198 | WX_DECLARE_GET_OBJC_CLASS(wxNSViewNotificationObserver,NSObject) |
| 199 | |
| 200 | @implementation wxNSViewNotificationObserver : NSObject |
| 201 | |
| 202 | - (void)notificationFrameChanged: (NSNotification *)notification; |
| 203 | { |
| 204 | wxCocoaNSView *win = wxCocoaNSView::GetFromCocoa([notification object]); |
| 205 | wxCHECK_RET(win,wxT("notificationFrameChanged received but no wxWindow exists")); |
| 206 | win->Cocoa_FrameChanged(); |
| 207 | } |
| 208 | |
| 209 | - (void)synthesizeMouseMovedForView: (NSView *)theView |
| 210 | { |
| 211 | wxCocoaNSView *win = wxCocoaNSView::GetFromCocoa(theView); |
| 212 | wxCHECK_RET(win,wxT("synthesizeMouseMovedForView received but no wxWindow exists")); |
| 213 | win->Cocoa_synthesizeMouseMoved(); |
| 214 | } |
| 215 | |
| 216 | @end // implementation wxNSViewNotificationObserver |
| 217 | WX_IMPLEMENT_GET_OBJC_CLASS(wxNSViewNotificationObserver,NSObject) |
| 218 | |
| 219 | // New CF-retained observer (this should have been using wxObjcAutoRefFromAlloc to begin with) |
| 220 | wxObjcAutoRefFromAlloc<wxNSViewNotificationObserver*> s_cocoaNSViewObserver([[WX_GET_OBJC_CLASS(wxNSViewNotificationObserver) alloc] init]); |
| 221 | // For compatibility with old code |
| 222 | id wxCocoaNSView::sm_cocoaObserver = s_cocoaNSViewObserver; |