]> git.saurik.com Git - wxWidgets.git/blob - src/osx/cocoa/window.mm
adding scroll wheel support
[wxWidgets.git] / src / osx / cocoa / window.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/cocoa/window.mm
3 // Purpose: widgets (non tlw) for cocoa
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 2008-06-20
7 // RCS-ID: $Id: window.mm 48805 2007-09-19 14:52:25Z SC $
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #ifndef WX_PRECOMP
15 #include "wx/nonownedwnd.h"
16 #include "wx/log.h"
17 #endif
18
19 #ifdef __WXMAC__
20 #include "wx/osx/private.h"
21 #endif
22
23 #if wxUSE_CARET
24 #include "wx/caret.h"
25 #endif
26
27 #if wxUSE_DRAG_AND_DROP
28 #include "wx/dnd.h"
29 #endif
30
31 #include <objc/objc-runtime.h>
32
33 NSRect wxOSXGetFrameForControl( wxWindowMac* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin )
34 {
35 int x, y, w, h ;
36
37 window->MacGetBoundsForControl( pos , size , x , y, w, h , adjustForOrigin ) ;
38 wxRect bounds(x,y,w,h);
39 NSView* sv = (window->GetParent()->GetHandle() );
40
41 return wxToNSRect( sv, bounds );
42 }
43
44 @interface wxNSView : NSView
45 {
46 }
47
48 - (BOOL) canBecomeKeyView;
49
50 @end // wxNSView
51
52 @interface NSView(PossibleMethods)
53 - (void)setTitle:(NSString *)aString;
54 - (void)setStringValue:(NSString *)aString;
55 - (void)setIntValue:(int)anInt;
56 - (void)setFloatValue:(float)aFloat;
57 - (void)setDoubleValue:(double)aDouble;
58
59 - (double)minValue;
60 - (double)maxValue;
61 - (void)setMinValue:(double)aDouble;
62 - (void)setMaxValue:(double)aDouble;
63
64 - (void)sizeToFit;
65
66 - (BOOL)isEnabled;
67 - (void)setEnabled:(BOOL)flag;
68
69 - (void)setImage:(NSImage *)image;
70 - (void)setControlSize:(NSControlSize)size;
71
72 - (id)contentView;
73
74 - (void)setTarget:(id)anObject;
75 - (void)setAction:(SEL)aSelector;
76 - (void)setDoubleAction:(SEL)aSelector;
77 @end
78
79 long wxOSXTranslateCocoaKey( int unichar )
80 {
81 long retval = unichar;
82 switch( unichar )
83 {
84 case NSUpArrowFunctionKey :
85 retval = WXK_UP;
86 break;
87 case NSDownArrowFunctionKey :
88 retval = WXK_DOWN;
89 break;
90 case NSLeftArrowFunctionKey :
91 retval = WXK_LEFT;
92 break;
93 case NSRightArrowFunctionKey :
94 retval = WXK_RIGHT;
95 break;
96 case NSInsertFunctionKey :
97 retval = WXK_INSERT;
98 break;
99 case NSDeleteFunctionKey :
100 retval = WXK_DELETE;
101 break;
102 case NSHomeFunctionKey :
103 retval = WXK_HOME;
104 break;
105 // case NSBeginFunctionKey :
106 // retval = WXK_BEGIN;
107 // break;
108 case NSEndFunctionKey :
109 retval = WXK_END;
110 break;
111 case NSPageUpFunctionKey :
112 retval = WXK_PAGEUP;
113 break;
114 case NSPageDownFunctionKey :
115 retval = WXK_PAGEDOWN;
116 break;
117 case NSHelpFunctionKey :
118 retval = WXK_HELP;
119 break;
120
121 default :
122 if ( unichar >= NSF1FunctionKey && unichar >= NSF24FunctionKey )
123 retval = WXK_F1 + (unichar - NSF1FunctionKey );
124 break;
125 }
126 return retval;
127 }
128
129 void SetupKeyEvent( wxKeyEvent &wxevent , NSEvent * nsEvent )
130 {
131 UInt32 modifiers = [nsEvent modifierFlags] ;
132 int eventType = [nsEvent type];
133
134 wxevent.m_shiftDown = modifiers & NSShiftKeyMask;
135 wxevent.m_controlDown = modifiers & NSControlKeyMask;
136 wxevent.m_altDown = modifiers & NSAlternateKeyMask;
137 wxevent.m_metaDown = modifiers & NSCommandKeyMask;
138
139 wxevent.m_rawCode = [nsEvent keyCode];
140 wxevent.m_rawFlags = modifiers;
141
142 wxevent.SetTimestamp( [nsEvent timestamp] * 1000.0 ) ;
143 switch (eventType)
144 {
145 case NSKeyDown :
146 wxevent.SetEventType( wxEVT_KEY_DOWN ) ;
147 break;
148 case NSKeyUp :
149 wxevent.SetEventType( wxEVT_KEY_UP ) ;
150 break;
151 case NSFlagsChanged :
152 // setup common code here
153 break;
154 default :
155 break ;
156 }
157
158 wxString chars;
159 if ( eventType != NSFlagsChanged )
160 {
161 NSString* nschars = [nsEvent characters];
162 if ( nschars )
163 {
164 wxCFStringRef cfchars((CFStringRef)[nschars retain]);
165 chars = cfchars.AsString();
166 }
167 }
168
169 int unichar = chars.Length() > 0 ? chars[0] : 0;
170 long keyval = wxOSXTranslateCocoaKey(unichar) ;
171 if ( keyval == unichar && ( wxevent.GetEventType() == wxEVT_KEY_UP || wxevent.GetEventType() == wxEVT_KEY_DOWN ) )
172 keyval = wxToupper( keyval ) ;
173
174 #if wxUSE_UNICODE
175 wxevent.m_uniChar = unichar;
176 #endif
177 wxevent.m_keyCode = keyval;
178 }
179
180 UInt32 g_lastButton = 0 ;
181 bool g_lastButtonWasFakeRight = false ;
182
183 void SetupMouseEvent( wxMouseEvent &wxevent , NSEvent * nsEvent )
184 {
185 int eventType = [nsEvent type];
186 UInt32 modifiers = [nsEvent modifierFlags] ;
187 wxPoint screenMouseLocation = wxFromNSPoint( NULL, [nsEvent locationInWindow]);
188
189 // these parameters are not given for all events
190 UInt32 button = [nsEvent buttonNumber];
191 UInt32 clickCount = 0;
192 if ( eventType != NSScrollWheel )
193 [nsEvent clickCount];
194
195 wxevent.m_x = screenMouseLocation.x;
196 wxevent.m_y = screenMouseLocation.y;
197 wxevent.m_shiftDown = modifiers & NSShiftKeyMask;
198 wxevent.m_controlDown = modifiers & NSControlKeyMask;
199 wxevent.m_altDown = modifiers & NSAlternateKeyMask;
200 wxevent.m_metaDown = modifiers & NSCommandKeyMask;
201 wxevent.m_clickCount = clickCount;
202 wxevent.SetTimestamp( [nsEvent timestamp] * 1000.0 ) ;
203
204 UInt32 mouseChord = 0;
205
206 switch (eventType)
207 {
208 case NSLeftMouseDown :
209 case NSLeftMouseDragged :
210 mouseChord = 1U;
211 break;
212 case NSRightMouseDown :
213 case NSRightMouseDragged :
214 mouseChord = 2U;
215 break;
216 case NSOtherMouseDown :
217 case NSOtherMouseDragged :
218 mouseChord = 4U;
219 break;
220 }
221
222 // a control click is interpreted as a right click
223 bool thisButtonIsFakeRight = false ;
224 if ( button == 0 && (modifiers & NSControlKeyMask) )
225 {
226 button = 1 ;
227 thisButtonIsFakeRight = true ;
228 }
229
230 // otherwise we report double clicks by connecting a left click with a ctrl-left click
231 if ( clickCount > 1 && button != g_lastButton )
232 clickCount = 1 ;
233
234 // we must make sure that our synthetic 'right' button corresponds in
235 // mouse down, moved and mouse up, and does not deliver a right down and left up
236 switch (eventType)
237 {
238 case NSLeftMouseDown :
239 case NSRightMouseDown :
240 case NSOtherMouseDown :
241 g_lastButton = button ;
242 g_lastButtonWasFakeRight = thisButtonIsFakeRight ;
243 break;
244 }
245
246 if ( button == 0 )
247 {
248 g_lastButton = 0 ;
249 g_lastButtonWasFakeRight = false ;
250 }
251 else if ( g_lastButton == 1 && g_lastButtonWasFakeRight )
252 button = g_lastButton ;
253
254 // Adjust the chord mask to remove the primary button and add the
255 // secondary button. It is possible that the secondary button is
256 // already pressed, e.g. on a mouse connected to a laptop, but this
257 // possibility is ignored here:
258 if( thisButtonIsFakeRight && ( mouseChord & 1U ) )
259 mouseChord = ((mouseChord & ~1U) | 2U);
260
261 if(mouseChord & 1U)
262 wxevent.m_leftDown = true ;
263 if(mouseChord & 2U)
264 wxevent.m_rightDown = true ;
265 if(mouseChord & 4U)
266 wxevent.m_middleDown = true ;
267
268 // translate into wx types
269 switch (eventType)
270 {
271 case NSLeftMouseDown :
272 case NSRightMouseDown :
273 case NSOtherMouseDown :
274 switch ( button )
275 {
276 case 0 :
277 wxevent.SetEventType( clickCount > 1 ? wxEVT_LEFT_DCLICK : wxEVT_LEFT_DOWN ) ;
278 break ;
279
280 case 1 :
281 wxevent.SetEventType( clickCount > 1 ? wxEVT_RIGHT_DCLICK : wxEVT_RIGHT_DOWN ) ;
282 break ;
283
284 case 2 :
285 wxevent.SetEventType( clickCount > 1 ? wxEVT_MIDDLE_DCLICK : wxEVT_MIDDLE_DOWN ) ;
286 break ;
287
288 default:
289 break ;
290 }
291 break ;
292
293 case NSLeftMouseUp :
294 case NSRightMouseUp :
295 case NSOtherMouseUp :
296 switch ( button )
297 {
298 case 0 :
299 wxevent.SetEventType( wxEVT_LEFT_UP ) ;
300 break ;
301
302 case 1 :
303 wxevent.SetEventType( wxEVT_RIGHT_UP ) ;
304 break ;
305
306 case 2 :
307 wxevent.SetEventType( wxEVT_MIDDLE_UP ) ;
308 break ;
309
310 default:
311 break ;
312 }
313 break ;
314
315 case NSScrollWheel :
316 {
317 wxevent.SetEventType( wxEVT_MOUSEWHEEL ) ;
318 wxevent.m_wheelDelta = 1;
319 wxevent.m_linesPerAction = 1;
320 if ( abs([nsEvent deltaX]) > abs([nsEvent deltaY]) )
321 {
322 wxevent.m_wheelAxis = 1;
323 wxevent.m_wheelRotation = [nsEvent deltaX] > 0.0 ? 1 : -1;
324 }
325 else
326 {
327 wxevent.m_wheelRotation = [nsEvent deltaY] > 0.0 ? 1 : -1;
328 }
329 }
330 break ;
331
332 case NSMouseEntered :
333 case NSMouseExited :
334 case NSLeftMouseDragged :
335 case NSRightMouseDragged :
336 case NSOtherMouseDragged :
337 case NSMouseMoved :
338 wxevent.SetEventType( wxEVT_MOTION ) ;
339 break;
340 default :
341 break ;
342 }
343 }
344
345 @implementation wxNSView
346
347 + (void)initialize
348 {
349 static BOOL initialized = NO;
350 if (!initialized)
351 {
352 initialized = YES;
353 wxOSXCocoaClassAddWXMethods( self );
354 }
355 }
356
357 - (BOOL) canBecomeKeyView
358 {
359 return YES;
360 }
361
362 @end // wxNSView
363
364 //
365 // event handlers
366 //
367
368 #if wxUSE_DRAG_AND_DROP
369
370 // see http://lists.apple.com/archives/Cocoa-dev/2005/Jul/msg01244.html
371 // for details on the NSPasteboard -> PasteboardRef conversion
372
373 NSDragOperation wxOSX_draggingEntered( id self, SEL _cmd, id <NSDraggingInfo>sender )
374 {
375 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
376 if (impl == NULL)
377 return NSDragOperationNone;
378
379 return impl->draggingEntered(sender, self, _cmd);
380 }
381
382 void wxOSX_draggingExited( id self, SEL _cmd, id <NSDraggingInfo> sender )
383 {
384 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
385 if (impl == NULL)
386 return ;
387
388 return impl->draggingExited(sender, self, _cmd);
389 }
390
391 NSDragOperation wxOSX_draggingUpdated( id self, SEL _cmd, id <NSDraggingInfo>sender )
392 {
393 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
394 if (impl == NULL)
395 return NSDragOperationNone;
396
397 return impl->draggingUpdated(sender, self, _cmd);
398 }
399
400 BOOL wxOSX_performDragOperation( id self, SEL _cmd, id <NSDraggingInfo> sender )
401 {
402 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
403 if (impl == NULL)
404 return NSDragOperationNone;
405
406 return impl->performDragOperation(sender, self, _cmd) ? YES:NO ;
407 }
408
409 void wxOSX_mouseEvent(NSView* self, SEL _cmd, NSEvent *event)
410 {
411 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
412 if (impl == NULL)
413 return;
414
415 impl->mouseEvent(event, self, _cmd);
416 }
417
418 void wxOSX_keyEvent(NSView* self, SEL _cmd, NSEvent *event)
419 {
420 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
421 if (impl == NULL)
422 return;
423
424 impl->keyEvent(event, self, _cmd);
425 }
426
427 BOOL wxOSX_performKeyEquivalent(NSView* self, SEL _cmd, NSEvent *event)
428 {
429 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
430 if (impl == NULL)
431 return NO;
432
433 return impl->performKeyEquivalent(event, self, _cmd);
434 }
435
436 BOOL wxOSX_becomeFirstResponder(NSView* self, SEL _cmd)
437 {
438 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
439 if (impl == NULL)
440 return NO;
441
442 return impl->becomeFirstResponder(self, _cmd);
443 }
444
445 BOOL wxOSX_resignFirstResponder(NSView* self, SEL _cmd)
446 {
447 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
448 if (impl == NULL)
449 return NO;
450
451 return impl->resignFirstResponder(self, _cmd);
452 }
453
454 void wxOSX_resetCursorRects(NSView* self, SEL _cmd)
455 {
456 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
457 if (impl == NULL)
458 return;
459
460 impl->resetCursorRects(self, _cmd);
461 }
462
463 BOOL wxOSX_isFlipped(NSView* self, SEL _cmd)
464 {
465 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
466 if (impl == NULL)
467 return NO;
468
469 return impl->isFlipped(self, _cmd) ? YES:NO;
470 }
471
472 void wxOSX_drawRect(NSView* self, SEL _cmd, NSRect rect)
473 {
474 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
475 if (impl == NULL)
476 return;
477
478 return impl->drawRect(&rect, self, _cmd);
479 }
480
481 void wxOSX_clickedAction(NSView* self, SEL _cmd, id sender)
482 {
483 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
484 if (impl == NULL)
485 return;
486
487 impl->clickedAction(self, _cmd, sender);
488 }
489
490 void wxOSX_doubleClickedAction(NSView* self, SEL _cmd, id sender)
491 {
492 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
493 if (impl == NULL)
494 return;
495
496 impl->doubleClickedAction(self, _cmd, sender);
497 }
498
499 unsigned int wxWidgetCocoaImpl::draggingEntered(void* s, WXWidget slf, void *_cmd)
500 {
501 id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s;
502 NSPasteboard *pboard = [sender draggingPasteboard];
503 NSDragOperation sourceDragMask = [sender draggingSourceOperationMask];
504
505 wxWindow* wxpeer = GetWXPeer();
506 if ( wxpeer == NULL )
507 return NSDragOperationNone;
508
509 wxDropTarget* target = wxpeer->GetDropTarget();
510 if ( target == NULL )
511 return NSDragOperationNone;
512
513 wxDragResult result = wxDragNone;
514 wxPoint pt = wxFromNSPoint( m_osxView, [sender draggingLocation] );
515
516 if ( sourceDragMask & NSDragOperationLink )
517 result = wxDragLink;
518 else if ( sourceDragMask & NSDragOperationCopy )
519 result = wxDragCopy;
520 else if ( sourceDragMask & NSDragOperationMove )
521 result = wxDragMove;
522
523 PasteboardRef pboardRef;
524 PasteboardCreate((CFStringRef)[pboard name], &pboardRef);
525 target->SetCurrentDragPasteboard(pboardRef);
526 result = target->OnEnter(pt.x, pt.y, result);
527 CFRelease(pboardRef);
528
529 NSDragOperation nsresult = NSDragOperationNone;
530 switch (result )
531 {
532 case wxDragLink:
533 nsresult = NSDragOperationLink;
534 case wxDragMove:
535 nsresult = NSDragOperationMove;
536 case wxDragCopy:
537 nsresult = NSDragOperationCopy;
538 default :
539 break;
540 }
541 return nsresult;
542 }
543
544 void wxWidgetCocoaImpl::draggingExited(void* s, WXWidget slf, void *_cmd)
545 {
546 id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s;
547 NSPasteboard *pboard = [sender draggingPasteboard];
548
549 wxWindow* wxpeer = GetWXPeer();
550 if ( wxpeer == NULL )
551 return;
552
553 wxDropTarget* target = wxpeer->GetDropTarget();
554 if ( target == NULL )
555 return;
556
557 PasteboardRef pboardRef;
558 PasteboardCreate((CFStringRef)[pboard name], &pboardRef);
559 target->SetCurrentDragPasteboard(pboardRef);
560 target->OnLeave();
561 CFRelease(pboardRef);
562 }
563
564 unsigned int wxWidgetCocoaImpl::draggingUpdated(void* s, WXWidget slf, void *_cmd)
565 {
566 id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s;
567 NSPasteboard *pboard = [sender draggingPasteboard];
568 NSDragOperation sourceDragMask = [sender draggingSourceOperationMask];
569
570 wxWindow* wxpeer = GetWXPeer();
571 if ( wxpeer == NULL )
572 return NSDragOperationNone;
573
574 wxDropTarget* target = wxpeer->GetDropTarget();
575 if ( target == NULL )
576 return NSDragOperationNone;
577
578 wxDragResult result = wxDragNone;
579 wxPoint pt = wxFromNSPoint( m_osxView, [sender draggingLocation] );
580
581 if ( sourceDragMask & NSDragOperationLink )
582 result = wxDragLink;
583 else if ( sourceDragMask & NSDragOperationCopy )
584 result = wxDragCopy;
585 else if ( sourceDragMask & NSDragOperationMove )
586 result = wxDragMove;
587
588 PasteboardRef pboardRef;
589 PasteboardCreate((CFStringRef)[pboard name], &pboardRef);
590 target->SetCurrentDragPasteboard(pboardRef);
591 result = target->OnDragOver(pt.x, pt.y, result);
592 CFRelease(pboardRef);
593
594 NSDragOperation nsresult = NSDragOperationNone;
595 switch (result )
596 {
597 case wxDragLink:
598 nsresult = NSDragOperationLink;
599 case wxDragMove:
600 nsresult = NSDragOperationMove;
601 case wxDragCopy:
602 nsresult = NSDragOperationCopy;
603 default :
604 break;
605 }
606 return nsresult;
607 }
608
609 bool wxWidgetCocoaImpl::performDragOperation(void* s, WXWidget slf, void *_cmd)
610 {
611 id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s;
612
613 NSPasteboard *pboard = [sender draggingPasteboard];
614 NSDragOperation sourceDragMask = [sender draggingSourceOperationMask];
615
616 wxWindow* wxpeer = GetWXPeer();
617 wxDropTarget* target = wxpeer->GetDropTarget();
618 wxDragResult result = wxDragNone;
619 wxPoint pt = wxFromNSPoint( m_osxView, [sender draggingLocation] );
620
621 if ( sourceDragMask & NSDragOperationLink )
622 result = wxDragLink;
623 else if ( sourceDragMask & NSDragOperationCopy )
624 result = wxDragCopy;
625 else if ( sourceDragMask & NSDragOperationMove )
626 result = wxDragMove;
627
628 PasteboardRef pboardRef;
629 PasteboardCreate((CFStringRef)[pboard name], &pboardRef);
630 target->SetCurrentDragPasteboard(pboardRef);
631 result = target->OnData(pt.x, pt.y, result);
632 CFRelease(pboardRef);
633
634 return result != wxDragNone;
635 }
636
637 #endif
638
639 typedef void (*wxOSX_EventHandlerPtr)(NSView* self, SEL _cmd, NSEvent *event);
640 typedef BOOL (*wxOSX_PerformKeyEventHandlerPtr)(NSView* self, SEL _cmd, NSEvent *event);
641 typedef BOOL (*wxOSX_FocusHandlerPtr)(NSView* self, SEL _cmd);
642 typedef BOOL (*wxOSX_ResetCursorRectsHandlerPtr)(NSView* self, SEL _cmd);
643 typedef BOOL (*wxOSX_DrawRectHandlerPtr)(NSView* self, SEL _cmd, NSRect rect);
644
645 void wxWidgetCocoaImpl::mouseEvent(WX_NSEvent event, WXWidget slf, void *_cmd)
646 {
647 if ( !DoHandleMouseEvent(event) )
648 {
649 wxOSX_EventHandlerPtr superimpl = (wxOSX_EventHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
650 superimpl(slf, (SEL)_cmd, event);
651 }
652 }
653
654 void wxWidgetCocoaImpl::keyEvent(WX_NSEvent event, WXWidget slf, void *_cmd)
655 {
656 if ( !DoHandleKeyEvent(event) )
657 {
658 wxOSX_EventHandlerPtr superimpl = (wxOSX_EventHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
659 superimpl(slf, (SEL)_cmd, event);
660 }
661 }
662
663 bool wxWidgetCocoaImpl::performKeyEquivalent(WX_NSEvent event, WXWidget slf, void *_cmd)
664 {
665 if ( !DoHandleKeyEvent(event) )
666 {
667 wxOSX_PerformKeyEventHandlerPtr superimpl = (wxOSX_PerformKeyEventHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
668 return superimpl(slf, (SEL)_cmd, event);
669 }
670
671 return YES;
672 }
673
674 bool wxWidgetCocoaImpl::becomeFirstResponder(WXWidget slf, void *_cmd)
675 {
676 wxOSX_FocusHandlerPtr superimpl = (wxOSX_FocusHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
677 BOOL r = superimpl(slf, (SEL)_cmd);
678 if ( r )
679 DoNotifyFocusEvent( true );
680 return r;
681 }
682
683 bool wxWidgetCocoaImpl::resignFirstResponder(WXWidget slf, void *_cmd)
684 {
685 wxOSX_FocusHandlerPtr superimpl = (wxOSX_FocusHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
686 BOOL r = superimpl(slf, (SEL)_cmd);
687 if ( r )
688 DoNotifyFocusEvent( false );
689 return r;
690 }
691
692 void wxWidgetCocoaImpl::resetCursorRects(WXWidget slf, void *_cmd)
693 {
694 wxWindow* wxpeer = GetWXPeer();
695 if ( wxpeer )
696 {
697 NSCursor *cursor = (NSCursor*)wxpeer->GetCursor().GetHCURSOR();
698 if (cursor == NULL)
699 {
700 wxOSX_ResetCursorRectsHandlerPtr superimpl = (wxOSX_ResetCursorRectsHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
701 superimpl(slf, (SEL)_cmd);
702 }
703 else
704 [slf addCursorRect: [slf bounds]
705 cursor: cursor];
706 }
707 }
708
709 bool wxWidgetCocoaImpl::isFlipped(WXWidget slf, void *_cmd)
710 {
711 return m_isFlipped;
712 }
713
714
715 #define OSX_DEBUG_DRAWING 0
716
717 void wxWidgetCocoaImpl::drawRect(void* rect, WXWidget slf, void *_cmd)
718 {
719 CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
720 CGContextSaveGState( context );
721
722 #if OSX_DEBUG_DRAWING
723 CGContextBeginPath( context );
724 CGContextMoveToPoint(context, 0, 0);
725 NSRect bounds = [self bounds];
726 CGContextAddLineToPoint(context, 10, 0);
727 CGContextMoveToPoint(context, 0, 0);
728 CGContextAddLineToPoint(context, 0, 10);
729 CGContextMoveToPoint(context, bounds.size.width, bounds.size.height);
730 CGContextAddLineToPoint(context, bounds.size.width, bounds.size.height-10);
731 CGContextMoveToPoint(context, bounds.size.width, bounds.size.height);
732 CGContextAddLineToPoint(context, bounds.size.width-10, bounds.size.height);
733 CGContextClosePath( context );
734 CGContextStrokePath(context);
735 #endif
736
737 if ( !m_isFlipped )
738 {
739 CGContextTranslateCTM( context, 0, [m_osxView bounds].size.height );
740 CGContextScaleCTM( context, 1, -1 );
741 }
742
743 wxRegion updateRgn;
744 const NSRect *rects;
745 NSInteger count;
746
747 [slf getRectsBeingDrawn:&rects count:&count];
748 for ( int i = 0 ; i < count ; ++i )
749 {
750 updateRgn.Union(wxFromNSRect(slf, rects[i]) );
751 }
752
753 wxWindow* wxpeer = GetWXPeer();
754 wxpeer->GetUpdateRegion() = updateRgn;
755 wxpeer->MacSetCGContextRef( context );
756
757 wxPaintEvent event;
758 event.SetTimestamp(0); // todo
759 event.SetEventObject(wxpeer);
760 bool handled = wxpeer->HandleWindowEvent(event);
761
762 CGContextRestoreGState( context );
763
764 if ( !handled )
765 {
766 // call super
767 SEL _cmd = @selector(drawRect:);
768 wxOSX_DrawRectHandlerPtr superimpl = (wxOSX_DrawRectHandlerPtr) [[slf superclass] instanceMethodForSelector:_cmd];
769 superimpl(slf, _cmd, *(NSRect*)rect);
770 }
771 }
772
773 void wxWidgetCocoaImpl::clickedAction( WXWidget slf, void *_cmd, void *sender)
774 {
775 wxWindow* wxpeer = (wxWindow*) GetWXPeer();
776 if ( wxpeer )
777 wxpeer->OSXHandleClicked(0);
778 }
779
780 void wxWidgetCocoaImpl::doubleClickedAction( WXWidget slf, void *_cmd, void *sender)
781 {
782 }
783
784 //
785
786 #if OBJC_API_VERSION >= 2
787
788 #define wxOSX_CLASS_ADD_METHOD( c, s, i, t ) \
789 class_addMethod(c, s, i, t );
790
791 #else
792
793 #define wxOSX_CLASS_ADD_METHOD( c, s, i, t ) \
794 { s, t, i },
795
796 #endif
797
798 void wxOSXCocoaClassAddWXMethods(Class c)
799 {
800
801 #if OBJC_API_VERSION < 2
802 static objc_method wxmethods[] =
803 {
804 #endif
805
806 wxOSX_CLASS_ADD_METHOD(c, @selector(mouseDown:), (IMP) wxOSX_mouseEvent, "v@:@" )
807 wxOSX_CLASS_ADD_METHOD(c, @selector(rightMouseDown:), (IMP) wxOSX_mouseEvent, "v@:@" )
808 wxOSX_CLASS_ADD_METHOD(c, @selector(otherMouseDown:), (IMP) wxOSX_mouseEvent, "v@:@" )
809
810 wxOSX_CLASS_ADD_METHOD(c, @selector(mouseUp:), (IMP) wxOSX_mouseEvent, "v@:@" )
811 wxOSX_CLASS_ADD_METHOD(c, @selector(rightMouseUp:), (IMP) wxOSX_mouseEvent, "v@:@" )
812 wxOSX_CLASS_ADD_METHOD(c, @selector(otherMouseUp:), (IMP) wxOSX_mouseEvent, "v@:@" )
813
814 wxOSX_CLASS_ADD_METHOD(c, @selector(mouseMoved:), (IMP) wxOSX_mouseEvent, "v@:@" )
815
816 wxOSX_CLASS_ADD_METHOD(c, @selector(mouseDragged:), (IMP) wxOSX_mouseEvent, "v@:@" )
817 wxOSX_CLASS_ADD_METHOD(c, @selector(rightMouseDragged:), (IMP) wxOSX_mouseEvent, "v@:@" )
818 wxOSX_CLASS_ADD_METHOD(c, @selector(otherMouseDragged:), (IMP) wxOSX_mouseEvent, "v@:@" )
819
820 wxOSX_CLASS_ADD_METHOD(c, @selector(scrollWheel:), (IMP) wxOSX_mouseEvent, "v@:@" )
821 wxOSX_CLASS_ADD_METHOD(c, @selector(mouseEntered:), (IMP) wxOSX_mouseEvent, "v@:@" )
822 wxOSX_CLASS_ADD_METHOD(c, @selector(mouseExited:), (IMP) wxOSX_mouseEvent, "v@:@" )
823
824 wxOSX_CLASS_ADD_METHOD(c, @selector(keyDown:), (IMP) wxOSX_keyEvent, "v@:@" )
825 wxOSX_CLASS_ADD_METHOD(c, @selector(keyUp:), (IMP) wxOSX_keyEvent, "v@:@" )
826 wxOSX_CLASS_ADD_METHOD(c, @selector(flagsChanged:), (IMP) wxOSX_keyEvent, "v@:@" )
827
828 wxOSX_CLASS_ADD_METHOD(c, @selector(performKeyEquivalent:), (IMP) wxOSX_performKeyEquivalent, "v@:@" )
829
830
831 wxOSX_CLASS_ADD_METHOD(c, @selector(becomeFirstResponder), (IMP) wxOSX_becomeFirstResponder, "c@:" )
832 wxOSX_CLASS_ADD_METHOD(c, @selector(resignFirstResponder), (IMP) wxOSX_resignFirstResponder, "c@:" )
833 wxOSX_CLASS_ADD_METHOD(c, @selector(resetCursorRects), (IMP) wxOSX_resetCursorRects, "v@:" )
834
835 wxOSX_CLASS_ADD_METHOD(c, @selector(isFlipped), (IMP) wxOSX_isFlipped, "c@:" )
836 wxOSX_CLASS_ADD_METHOD(c, @selector(drawRect:), (IMP) wxOSX_drawRect, "v@:{_NSRect={_NSPoint=ff}{_NSSize=ff}}" )
837
838 wxOSX_CLASS_ADD_METHOD(c, @selector(clickedAction:), (IMP) wxOSX_clickedAction, "v@:@" )
839 wxOSX_CLASS_ADD_METHOD(c, @selector(doubleClickedAction:), (IMP) wxOSX_doubleClickedAction, "v@:@" )
840
841 #if wxUSE_DRAG_AND_DROP
842 wxOSX_CLASS_ADD_METHOD(c, @selector(draggingEntered:), (IMP) wxOSX_draggingEntered, "I@:@" )
843 wxOSX_CLASS_ADD_METHOD(c, @selector(draggingUpdated:), (IMP) wxOSX_draggingUpdated, "I@:@" )
844 wxOSX_CLASS_ADD_METHOD(c, @selector(draggingExited:), (IMP) wxOSX_draggingExited, "v@:@" )
845 wxOSX_CLASS_ADD_METHOD(c, @selector(performDragOperation:), (IMP) wxOSX_performDragOperation, "c@:@" )
846 #endif
847
848 #if OBJC_API_VERSION < 2
849 } ;
850 static int method_count = WXSIZEOF( wxmethods );
851 static objc_method_list *wxmethodlist = NULL;
852 if ( wxmethodlist == NULL )
853 {
854 wxmethodlist = (objc_method_list*) malloc(sizeof(objc_method_list) + sizeof(wxmethods) );
855 memcpy( &wxmethodlist->method_list[0], &wxmethods[0], sizeof(wxmethods) );
856 wxmethodlist->method_count = method_count;
857 wxmethodlist->obsolete = 0;
858 }
859 class_addMethods( c, wxmethodlist );
860 #endif
861 }
862
863 //
864 // C++ implementation class
865 //
866
867 IMPLEMENT_DYNAMIC_CLASS( wxWidgetCocoaImpl , wxWidgetImpl )
868
869 wxWidgetCocoaImpl::wxWidgetCocoaImpl( wxWindowMac* peer , WXWidget w, bool isRootControl ) :
870 wxWidgetImpl( peer, isRootControl )
871 {
872 Init();
873 m_osxView = w;
874 }
875
876 wxWidgetCocoaImpl::wxWidgetCocoaImpl()
877 {
878 Init();
879 }
880
881 void wxWidgetCocoaImpl::Init()
882 {
883 m_osxView = NULL;
884 m_isFlipped = true;
885 }
886
887 wxWidgetCocoaImpl::~wxWidgetCocoaImpl()
888 {
889 RemoveAssociations( this );
890
891 if ( !IsRootControl() )
892 {
893 NSView *sv = [m_osxView superview];
894 if ( sv != nil )
895 [m_osxView removeFromSuperview];
896 }
897 [m_osxView release];
898 }
899
900 bool wxWidgetCocoaImpl::IsVisible() const
901 {
902 return [m_osxView isHiddenOrHasHiddenAncestor] == NO;
903 }
904
905 void wxWidgetCocoaImpl::SetVisibility( bool visible )
906 {
907 [m_osxView setHidden:(visible ? NO:YES)];
908 }
909
910 void wxWidgetCocoaImpl::Raise()
911 {
912 }
913
914 void wxWidgetCocoaImpl::Lower()
915 {
916 }
917
918 void wxWidgetCocoaImpl::ScrollRect( const wxRect *rect, int dx, int dy )
919 {
920 #if 1
921 SetNeedsDisplay() ;
922 #else
923 // We should do something like this, but it wasn't working in 10.4.
924 if (GetNeedsDisplay() )
925 {
926 SetNeedsDisplay() ;
927 }
928 NSRect r = wxToNSRect( [m_osxView superview], *rect );
929 NSSize offset = NSMakeSize((float)dx, (float)dy);
930 [m_osxView scrollRect:r by:offset];
931 #endif
932 }
933
934 void wxWidgetCocoaImpl::Move(int x, int y, int width, int height)
935 {
936 wxWindowMac* parent = GetWXPeer()->GetParent();
937 // under Cocoa we might have a contentView in the wxParent to which we have to
938 // adjust the coordinates
939 if (parent)
940 {
941 wxPoint pt(parent->GetClientAreaOrigin());
942 x -= pt.x;
943 y -= pt.y;
944 }
945 NSRect r = wxToNSRect( [m_osxView superview], wxRect(x,y,width, height) );
946 [m_osxView setFrame:r];
947 }
948
949 void wxWidgetCocoaImpl::GetPosition( int &x, int &y ) const
950 {
951 wxRect r = wxFromNSRect( [m_osxView superview], [m_osxView frame] );
952 x = r.GetLeft();
953 y = r.GetTop();
954 }
955
956 void wxWidgetCocoaImpl::GetSize( int &width, int &height ) const
957 {
958 NSRect rect = [m_osxView frame];
959 width = rect.size.width;
960 height = rect.size.height;
961 }
962
963 void wxWidgetCocoaImpl::GetContentArea( int&left, int &top, int &width, int &height ) const
964 {
965 if ( [m_osxView respondsToSelector:@selector(contentView) ] )
966 {
967 NSView* cv = [m_osxView contentView];
968
969 NSRect bounds = [m_osxView bounds];
970 NSRect rect = [cv frame];
971
972 int y = rect.origin.y;
973 int x = rect.origin.x;
974 if ( ![ m_osxView isFlipped ] )
975 y = bounds.size.height - (rect.origin.y + rect.size.height);
976 left = x;
977 top = y;
978 width = rect.size.width;
979 height = rect.size.height;
980 }
981 else
982 {
983 left = top = 0;
984 GetSize( width, height );
985 }
986 }
987
988 void wxWidgetCocoaImpl::SetNeedsDisplay( const wxRect* where )
989 {
990 if ( where )
991 [m_osxView setNeedsDisplayInRect:wxToNSRect(m_osxView, *where )];
992 else
993 [m_osxView setNeedsDisplay:YES];
994 }
995
996 bool wxWidgetCocoaImpl::GetNeedsDisplay() const
997 {
998 return [m_osxView needsDisplay];
999 }
1000
1001 bool wxWidgetCocoaImpl::CanFocus() const
1002 {
1003 return [m_osxView canBecomeKeyView] == YES;
1004 }
1005
1006 bool wxWidgetCocoaImpl::HasFocus() const
1007 {
1008 return ( [[m_osxView window] firstResponder] == m_osxView );
1009 }
1010
1011 bool wxWidgetCocoaImpl::SetFocus()
1012 {
1013 if ( [m_osxView canBecomeKeyView] == NO )
1014 return false;
1015
1016 [[m_osxView window] makeFirstResponder: m_osxView] ;
1017 return true;
1018 }
1019
1020
1021 void wxWidgetCocoaImpl::RemoveFromParent()
1022 {
1023 [m_osxView removeFromSuperview];
1024 }
1025
1026 void wxWidgetCocoaImpl::Embed( wxWidgetImpl *parent )
1027 {
1028 NSView* container = parent->GetWXWidget() ;
1029 wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
1030 [container addSubview:m_osxView];
1031 }
1032
1033 void wxWidgetCocoaImpl::SetBackgroundColour( const wxColour &WXUNUSED(col) )
1034 {
1035 // m_osxView.backgroundColor = [[UIColor alloc] initWithCGColor:col.GetCGColor()];
1036 }
1037
1038 void wxWidgetCocoaImpl::SetLabel( const wxString& title, wxFontEncoding encoding )
1039 {
1040 if ( [m_osxView respondsToSelector:@selector(setTitle:) ] )
1041 {
1042 wxCFStringRef cf( title , m_wxPeer->GetFont().GetEncoding() );
1043 [m_osxView setTitle:cf.AsNSString()];
1044 }
1045 }
1046
1047
1048 void wxWidgetImpl::Convert( wxPoint *pt , wxWidgetImpl *from , wxWidgetImpl *to )
1049 {
1050 NSPoint p = wxToNSPoint( from->GetWXWidget(), *pt );
1051 p = [from->GetWXWidget() convertPoint:p toView:to->GetWXWidget() ];
1052 *pt = wxFromNSPoint( to->GetWXWidget(), p );
1053 }
1054
1055 wxInt32 wxWidgetCocoaImpl::GetValue() const
1056 {
1057 return [(NSControl*)m_osxView intValue];
1058 }
1059
1060 void wxWidgetCocoaImpl::SetValue( wxInt32 v )
1061 {
1062 if ( [m_osxView respondsToSelector:@selector(setIntValue:)] )
1063 {
1064 [m_osxView setIntValue:v];
1065 }
1066 else if ( [m_osxView respondsToSelector:@selector(setFloatValue:)] )
1067 {
1068 [m_osxView setFloatValue:(double)v];
1069 }
1070 else if ( [m_osxView respondsToSelector:@selector(setDoubleValue:)] )
1071 {
1072 [m_osxView setDoubleValue:(double)v];
1073 }
1074 }
1075
1076 void wxWidgetCocoaImpl::SetMinimum( wxInt32 v )
1077 {
1078 if ( [m_osxView respondsToSelector:@selector(setMinValue:)] )
1079 {
1080 [m_osxView setMinValue:(double)v];
1081 }
1082 }
1083
1084 void wxWidgetCocoaImpl::SetMaximum( wxInt32 v )
1085 {
1086 if ( [m_osxView respondsToSelector:@selector(setMaxValue:)] )
1087 {
1088 [m_osxView setMaxValue:(double)v];
1089 }
1090 }
1091
1092 wxInt32 wxWidgetCocoaImpl::GetMinimum() const
1093 {
1094 if ( [m_osxView respondsToSelector:@selector(getMinValue:)] )
1095 {
1096 return [m_osxView minValue];
1097 }
1098 return 0;
1099 }
1100
1101 wxInt32 wxWidgetCocoaImpl::GetMaximum() const
1102 {
1103 if ( [m_osxView respondsToSelector:@selector(getMaxValue:)] )
1104 {
1105 return [m_osxView maxValue];
1106 }
1107 return 0;
1108 }
1109
1110 void wxWidgetCocoaImpl::SetBitmap( const wxBitmap& bitmap )
1111 {
1112 if ( [m_osxView respondsToSelector:@selector(setImage:)] )
1113 {
1114 [m_osxView setImage:bitmap.GetNSImage()];
1115 }
1116 }
1117
1118 void wxWidgetCocoaImpl::SetupTabs( const wxNotebook& notebook)
1119 {
1120 // implementation in subclass
1121 }
1122
1123 void wxWidgetCocoaImpl::GetBestRect( wxRect *r ) const
1124 {
1125 r->x = r->y = r->width = r->height = 0;
1126 // if ( [m_osxView isKindOfClass:[NSControl class]] )
1127 if ( [m_osxView respondsToSelector:@selector(sizeToFit)] )
1128 {
1129 NSRect former = [m_osxView frame];
1130 [m_osxView sizeToFit];
1131 NSRect best = [m_osxView frame];
1132 [m_osxView setFrame:former];
1133 r->width = best.size.width;
1134 r->height = best.size.height;
1135 }
1136 }
1137
1138 bool wxWidgetCocoaImpl::IsEnabled() const
1139 {
1140 if ( [m_osxView respondsToSelector:@selector(isEnabled) ] )
1141 return [m_osxView isEnabled];
1142 return true;
1143 }
1144
1145 void wxWidgetCocoaImpl::Enable( bool enable )
1146 {
1147 if ( [m_osxView respondsToSelector:@selector(setEnabled:) ] )
1148 [m_osxView setEnabled:enable];
1149 }
1150
1151 void wxWidgetCocoaImpl::PulseGauge()
1152 {
1153 }
1154
1155 void wxWidgetCocoaImpl::SetScrollThumb( wxInt32 val, wxInt32 view )
1156 {
1157 }
1158
1159 void wxWidgetCocoaImpl::SetControlSize( wxWindowVariant variant )
1160 {
1161 NSControlSize size = NSRegularControlSize;
1162
1163 switch ( variant )
1164 {
1165 case wxWINDOW_VARIANT_NORMAL :
1166 size = NSRegularControlSize;
1167 break ;
1168
1169 case wxWINDOW_VARIANT_SMALL :
1170 size = NSSmallControlSize;
1171 break ;
1172
1173 case wxWINDOW_VARIANT_MINI :
1174 size = NSMiniControlSize;
1175 break ;
1176
1177 case wxWINDOW_VARIANT_LARGE :
1178 size = NSRegularControlSize;
1179 break ;
1180
1181 default:
1182 wxFAIL_MSG(_T("unexpected window variant"));
1183 break ;
1184 }
1185 if ( [m_osxView respondsToSelector:@selector(setControlSize:)] )
1186 [m_osxView setControlSize:size];
1187 }
1188
1189 void wxWidgetCocoaImpl::SetFont(wxFont const&, wxColour const&, long, bool)
1190 {
1191 // TODO
1192 }
1193
1194 void wxWidgetCocoaImpl::InstallEventHandler( WXWidget control )
1195 {
1196 WXWidget c = control ? control : (WXWidget) m_osxView;
1197 wxWidgetImpl::Associate( c, this ) ;
1198 if ([c respondsToSelector:@selector(setAction:)])
1199 {
1200 [c setTarget: c];
1201 [c setAction: @selector(clickedAction:)];
1202 if ([c respondsToSelector:@selector(setDoubleAction:)])
1203 {
1204 [c setDoubleAction: @selector(doubleClickedAction:)];
1205 }
1206
1207 }
1208 }
1209
1210 bool wxWidgetCocoaImpl::DoHandleKeyEvent(NSEvent *event)
1211 {
1212 wxKeyEvent wxevent(wxEVT_KEY_DOWN);
1213 SetupKeyEvent( wxevent, event );
1214
1215 return GetWXPeer()->OSXHandleKeyEvent(wxevent);
1216 }
1217
1218 bool wxWidgetCocoaImpl::DoHandleMouseEvent(NSEvent *event)
1219 {
1220 NSPoint clickLocation;
1221 clickLocation = [m_osxView convertPoint:[event locationInWindow] fromView:nil];
1222 wxPoint pt = wxFromNSPoint( m_osxView, clickLocation );
1223 wxMouseEvent wxevent(wxEVT_LEFT_DOWN);
1224 SetupMouseEvent( wxevent , event ) ;
1225 wxevent.m_x = pt.x;
1226 wxevent.m_y = pt.y;
1227
1228 return GetWXPeer()->HandleWindowEvent(wxevent);
1229 }
1230
1231 void wxWidgetCocoaImpl::DoNotifyFocusEvent(bool receivedFocus)
1232 {
1233 wxWindow* thisWindow = GetWXPeer();
1234 if ( thisWindow->MacGetTopLevelWindow() && NeedsFocusRect() )
1235 {
1236 thisWindow->MacInvalidateBorders();
1237 }
1238
1239 if ( receivedFocus )
1240 {
1241 wxLogTrace(_T("Focus"), _T("focus set(%p)"), static_cast<void*>(thisWindow));
1242 wxChildFocusEvent eventFocus((wxWindow*)thisWindow);
1243 thisWindow->HandleWindowEvent(eventFocus);
1244
1245 #if wxUSE_CARET
1246 if ( thisWindow->GetCaret() )
1247 thisWindow->GetCaret()->OnSetFocus();
1248 #endif
1249
1250 wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId());
1251 event.SetEventObject(thisWindow);
1252 // TODO how to find out the targetFocusWindow ?
1253 // event.SetWindow(targetFocusWindow);
1254 thisWindow->HandleWindowEvent(event) ;
1255 }
1256 else // !receivedFocuss
1257 {
1258 #if wxUSE_CARET
1259 if ( thisWindow->GetCaret() )
1260 thisWindow->GetCaret()->OnKillFocus();
1261 #endif
1262
1263 wxLogTrace(_T("Focus"), _T("focus lost(%p)"), static_cast<void*>(thisWindow));
1264
1265 wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId());
1266 event.SetEventObject(thisWindow);
1267 // TODO how to find out the targetFocusWindow ?
1268 // event.SetWindow(targetFocusWindow);
1269 thisWindow->HandleWindowEvent(event) ;
1270 }
1271 }
1272
1273 void wxWidgetCocoaImpl::SetCursor(const wxCursor& cursor)
1274 {
1275 NSPoint location = [NSEvent mouseLocation];
1276 location = [[m_osxView window] convertScreenToBase:location];
1277 NSPoint locationInView = [m_osxView convertPoint:location fromView:nil];
1278
1279 if( NSMouseInRect(locationInView, [m_osxView bounds], YES) )
1280 {
1281 [(NSCursor*)cursor.GetHCURSOR() set];
1282 }
1283 [[m_osxView window] invalidateCursorRectsForView:m_osxView];
1284 }
1285
1286 void wxWidgetCocoaImpl::CaptureMouse()
1287 {
1288 [[m_osxView window] disableCursorRects];
1289 }
1290
1291 void wxWidgetCocoaImpl::ReleaseMouse()
1292 {
1293 [[m_osxView window] enableCursorRects];
1294 }
1295
1296 void wxWidgetCocoaImpl::SetFlipped(bool flipped)
1297 {
1298 m_isFlipped = flipped;
1299 }
1300
1301 //
1302 // Factory methods
1303 //
1304
1305 wxWidgetImpl* wxWidgetImpl::CreateUserPane( wxWindowMac* wxpeer, wxWindowMac* parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
1306 long style, long extraStyle)
1307 {
1308 NSRect r = wxOSXGetFrameForControl( wxpeer, pos , size ) ;
1309 wxNSView* v = [[wxNSView alloc] initWithFrame:r];
1310
1311 // temporary hook for dnd
1312 [v registerForDraggedTypes:[NSArray arrayWithObjects:
1313 NSStringPboardType, NSFilenamesPboardType, NSTIFFPboardType, NSPICTPboardType, NSPDFPboardType, nil]];
1314
1315 wxWidgetCocoaImpl* c = new wxWidgetCocoaImpl( wxpeer, v );
1316 return c;
1317 }
1318
1319 wxWidgetImpl* wxWidgetImpl::CreateContentView( wxNonOwnedWindow* now )
1320 {
1321 NSWindow* tlw = now->GetWXWindow();
1322 wxNSView* v = [[wxNSView alloc] initWithFrame:[[tlw contentView] frame]];
1323 wxWidgetCocoaImpl* c = new wxWidgetCocoaImpl( now, v, true );
1324 [tlw setContentView:v];
1325 return c;
1326 }