+
+#ifdef WXCOCOA_FILL_DUMMY_VIEW
+bool wxWindowCocoaHider::Cocoa_drawRect(const NSRect& rect)
+{
+ NSBezierPath *bezpath = [NSBezierPath bezierPathWithRect:rect];
+ [[NSColor greenColor] set];
+ [bezpath stroke];
+ [bezpath fill];
+ return true;
+}
+#endif //def WXCOCOA_FILL_DUMMY_VIEW
+
+// ========================================================================
+// wxFlippedNSClipView
+// ========================================================================
+@interface wxFlippedNSClipView : NSClipView
+- (BOOL)isFlipped;
+@end
+
+@implementation wxFlippedNSClipView : NSClipView
+- (BOOL)isFlipped
+{
+ return YES;
+}
+
+@end
+
+// ========================================================================
+// wxWindowCocoaScroller
+// ========================================================================
+wxWindowCocoaScroller::wxWindowCocoaScroller(wxWindow *owner)
+: m_owner(owner)
+{
+ wxAutoNSAutoreleasePool pool;
+ wxASSERT(owner);
+ wxASSERT(owner->GetNSView());
+ m_cocoaNSScrollView = [[NSScrollView alloc]
+ initWithFrame:[owner->GetNSView() frame]];
+ AssociateNSView(m_cocoaNSScrollView);
+
+ /* Replace the default NSClipView with a flipped one. This ensures
+ scrolling is "pinned" to the top-left instead of bottom-right. */
+ NSClipView *flippedClip = [[wxFlippedNSClipView alloc]
+ initWithFrame: [[m_cocoaNSScrollView contentView] frame]];
+ [m_cocoaNSScrollView setContentView:flippedClip];
+ [flippedClip release];
+
+ [m_cocoaNSScrollView setBackgroundColor: [NSColor windowBackgroundColor]];
+ [m_cocoaNSScrollView setHasHorizontalScroller: YES];
+ [m_cocoaNSScrollView setHasVerticalScroller: YES];
+ Encapsulate();
+}
+
+void wxWindowCocoaScroller::Encapsulate()
+{
+ // Set the scroll view autoresizingMask to match the current NSView
+ [m_cocoaNSScrollView setAutoresizingMask: [m_owner->GetNSView() autoresizingMask]];
+ [m_owner->GetNSView() setAutoresizingMask: NSViewNotSizable];
+ // NOTE: replaceSubView will cause m_cocaNSView to be released
+ // except when it hasn't been added into an NSView hierarchy in which
+ // case it doesn't need to be and this should work out to a no-op
+ m_owner->CocoaReplaceView(m_owner->GetNSView(), m_cocoaNSScrollView);
+ // The NSView is still retained by owner
+ [m_cocoaNSScrollView setDocumentView: m_owner->GetNSView()];
+ // Now it's also retained by the NSScrollView
+}
+
+void wxWindowCocoaScroller::Unencapsulate()
+{
+ [m_cocoaNSScrollView setDocumentView: nil];
+ m_owner->CocoaReplaceView(m_cocoaNSScrollView, m_owner->GetNSView());
+ if(![[m_owner->GetNSView() superview] isFlipped])
+ [m_owner->GetNSView() setAutoresizingMask: NSViewMinYMargin];
+}
+
+wxWindowCocoaScroller::~wxWindowCocoaScroller()
+{
+ DisassociateNSView(m_cocoaNSScrollView);
+ [m_cocoaNSScrollView release];
+}
+
+void wxWindowCocoaScroller::ClientSizeToSize(int &width, int &height)
+{
+ NSSize frameSize = [NSScrollView
+ frameSizeForContentSize: NSMakeSize(width,height)
+ hasHorizontalScroller: [m_cocoaNSScrollView hasHorizontalScroller]
+ hasVerticalScroller: [m_cocoaNSScrollView hasVerticalScroller]
+ borderType: [m_cocoaNSScrollView borderType]];
+ width = (int)frameSize.width;
+ height = (int)frameSize.height;
+}
+
+void wxWindowCocoaScroller::DoGetClientSize(int *x, int *y) const
+{
+ NSSize nssize = [m_cocoaNSScrollView contentSize];
+ if(x)
+ *x = (int)nssize.width;
+ if(y)
+ *y = (int)nssize.height;
+}
+
+void wxWindowCocoaScroller::Cocoa_FrameChanged(void)
+{
+ wxLogTrace(wxTRACE_COCOA,wxT("Cocoa_FrameChanged"));
+ wxSizeEvent event(m_owner->GetSize(), m_owner->GetId());
+ event.SetEventObject(m_owner);
+ m_owner->GetEventHandler()->ProcessEvent(event);
+}
+