From: David Elliott Date: Thu, 14 Aug 2003 19:47:28 +0000 (+0000) Subject: Implemented window scrolling using wxWindowCocoaScroller X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/816c52cf7c8abe346454f548f59ee889016d1ada Implemented window scrolling using wxWindowCocoaScroller git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@22888 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/cocoa/window.h b/include/wx/cocoa/window.h index 44865f4d20..1fbc20590b 100644 --- a/include/wx/cocoa/window.h +++ b/include/wx/cocoa/window.h @@ -19,6 +19,7 @@ #endif //def __OBJC__ class wxWindowCocoaHider; +class wxWindowCocoaScroller; // ======================================================================== // wxWindowCocoa @@ -29,6 +30,7 @@ class WXDLLEXPORT wxWindowCocoa: public wxWindowBase, protected wxCocoaNSView DECLARE_NO_COPY_CLASS(wxWindowCocoa) DECLARE_EVENT_TABLE() friend wxWindow *wxWindowBase::GetCapture(); + friend class wxWindowCocoaScroller; // ------------------------------------------------------------------------ // initialization // ------------------------------------------------------------------------ @@ -66,6 +68,7 @@ public: void CocoaAddChild(wxWindowCocoa *child); void CocoaRemoveFromParent(void); protected: + void CocoaCreateNSScrollView(); void InitMouseEvent(wxMouseEvent &event, WX_NSEvent cocoaEvent); virtual void Cocoa_FrameChanged(void); virtual bool Cocoa_drawRect(const NSRect &rect); @@ -84,6 +87,7 @@ protected: void SetNSView(WX_NSView cocoaNSView); WX_NSView m_cocoaNSView; wxWindowCocoaHider *m_cocoaHider; + wxWindowCocoaScroller *m_cocoaScroller; bool m_isInPaint; static wxWindow *sm_capturedWindow; virtual void CocoaReplaceView(WX_NSView oldView, WX_NSView newView); @@ -128,6 +132,7 @@ public: virtual int GetScrollThumb(int orient) const; virtual int GetScrollRange(int orient) const; virtual void ScrollWindow(int dx, int dy, const wxRect *rect = NULL); + virtual void DoSetVirtualSize(int x, int y); // Get the private handle (platform-dependent) virtual WXWidget GetHandle() const; // Convert client to screen coordinates diff --git a/src/cocoa/window.mm b/src/cocoa/window.mm index bd68943c13..97bcc62a5e 100644 --- a/src/cocoa/window.mm +++ b/src/cocoa/window.mm @@ -16,6 +16,9 @@ #import #import +#import +#import +#import // ======================================================================== // wxWindowCocoaHider @@ -35,6 +38,28 @@ private: wxWindowCocoaHider(); }; +// ======================================================================== +// wxWindowCocoaScroller +// ======================================================================== +class wxWindowCocoaScroller: protected wxCocoaNSView +{ + DECLARE_NO_COPY_CLASS(wxWindowCocoaScroller) +public: + wxWindowCocoaScroller(wxWindow *owner); + virtual ~wxWindowCocoaScroller(); + inline WX_NSScrollView GetNSScrollView() { return m_cocoaNSScrollView; } + void ClientSizeToSize(int &width, int &height); + void DoGetClientSize(int *x, int *y) const; + void Encapsulate(); + void Unencapsulate(); +protected: + wxWindowCocoa *m_owner; + WX_NSScrollView m_cocoaNSScrollView; + virtual void Cocoa_FrameChanged(void); +private: + wxWindowCocoaScroller(); +}; + // ======================================================================== // wxWindowCocoaHider // ======================================================================== @@ -61,6 +86,97 @@ void wxWindowCocoaHider::Cocoa_FrameChanged(void) [m_owner->GetNSViewForHiding() setFrame:[m_dummyNSView frame]]; } +// ======================================================================== +// wxFlippedNSClipView +// ======================================================================== +@interface wxFlippedNSClipView : NSClipView +- (BOOL)isFlipped; +@end + +@implementation wxFlippedNSClipView : NSClipView +- (BOOL)isFlipped +{ + return YES; +} + +@end + +// ======================================================================== +// wxWindowCocoaScroller +// ======================================================================== +wxWindowCocoaScroller::wxWindowCocoaScroller(wxWindow *owner) +: m_owner(owner) +{ + 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() +{ + // 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()); +} + +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 = frameSize.width; + height = frameSize.height; +} + +void wxWindowCocoaScroller::DoGetClientSize(int *x, int *y) const +{ + NSSize nssize = [m_cocoaNSScrollView contentSize]; + if(x) + *x = nssize.width; + if(y) + *y = nssize.height; +} + +void wxWindowCocoaScroller::Cocoa_FrameChanged(void) +{ + wxLogDebug("Cocoa_FrameChanged"); + wxSizeEvent event(m_owner->GetSize(), m_owner->GetId()); + event.SetEventObject(m_owner); + m_owner->GetEventHandler()->ProcessEvent(event); +} + // ======================================================================== // wxWindowCocoa // ======================================================================== @@ -83,6 +199,7 @@ void wxWindowCocoa::Init() m_cocoaNSView = NULL; m_cocoaHider = NULL; + m_cocoaScroller = NULL; m_isBeingDeleted = FALSE; m_isInPaint = FALSE; } @@ -123,6 +240,7 @@ wxWindow::~wxWindow() CocoaRemoveFromParent(); delete m_cocoaHider; + delete m_cocoaScroller; SetNSView(NULL); } @@ -156,12 +274,16 @@ WX_NSView wxWindowCocoa::GetNSViewForSuperview() const { return m_cocoaHider ? m_cocoaHider->GetNSView() - : m_cocoaNSView; + : m_cocoaScroller + ? m_cocoaScroller->GetNSScrollView() + : m_cocoaNSView; } WX_NSView wxWindowCocoa::GetNSViewForHiding() const { - return m_cocoaNSView; + return m_cocoaScroller + ? m_cocoaScroller->GetNSScrollView() + : m_cocoaNSView; } bool wxWindowCocoa::Cocoa_drawRect(const NSRect &rect) @@ -469,8 +591,10 @@ void wxWindow::DoClientToScreen(int *x, int *y) const void wxWindow::DoGetClientSize(int *x, int *y) const { wxLogDebug("DoGetClientSize:"); - wxWindowCocoa::DoGetSize(x,y); - // TODO: Actually account for menubar, borders, etc... + if(m_cocoaScroller) + m_cocoaScroller->DoGetClientSize(x,y); + else + wxWindowCocoa::DoGetSize(x,y); } void wxWindow::DoSetClientSize(int width, int height) @@ -528,6 +652,14 @@ void wxWindow::SetScrollPos(int orient, int pos, bool refresh) // TODO } +void wxWindow::CocoaCreateNSScrollView() +{ + if(!m_cocoaScroller) + { + m_cocoaScroller = new wxWindowCocoaScroller(this); + } +} + // New function that will replace some of the above. void wxWindow::SetScrollbar(int orient, int pos, int thumbVisible, int range, bool refresh) @@ -541,6 +673,13 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) // TODO } +void wxWindow::DoSetVirtualSize( int x, int y ) +{ + wxWindowBase::DoSetVirtualSize(x,y); + CocoaCreateNSScrollView(); + [m_cocoaNSView setFrameSize:NSMakeSize(m_virtualSize.x,m_virtualSize.y)]; +} + bool wxWindow::SetFont(const wxFont& font) { // TODO