Laid groundwork for scrolling.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@22775 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
David Elliott
2003-08-12 02:58:04 +00:00
parent 72eef31646
commit a82b814137
2 changed files with 104 additions and 47 deletions

View File

@@ -14,6 +14,8 @@
#include "wx/cocoa/NSView.h" #include "wx/cocoa/NSView.h"
class wxWindowCocoaHider;
// ======================================================================== // ========================================================================
// wxWindowCocoa // wxWindowCocoa
// ======================================================================== // ========================================================================
@@ -51,7 +53,12 @@ protected:
// Cocoa specifics // Cocoa specifics
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
public: public:
// Returns the content NSView (where children are added, drawing performed)
inline WX_NSView GetNSView() { return m_cocoaNSView; } inline WX_NSView GetNSView() { return m_cocoaNSView; }
// Returns the NSView suitable for use as a subview
WX_NSView GetNSViewForSuperview() const;
// Returns the NSView that may be hidden/is being hidden
WX_NSView GetNSViewForHiding() const;
void CocoaAddChild(wxWindowCocoa *child); void CocoaAddChild(wxWindowCocoa *child);
void CocoaRemoveFromParent(void); void CocoaRemoveFromParent(void);
protected: protected:
@@ -72,9 +79,10 @@ protected:
virtual bool Cocoa_otherMouseUp(WX_NSEvent theEvent); virtual bool Cocoa_otherMouseUp(WX_NSEvent theEvent);
void SetNSView(WX_NSView cocoaNSView); void SetNSView(WX_NSView cocoaNSView);
WX_NSView m_cocoaNSView; WX_NSView m_cocoaNSView;
WX_NSView m_dummyNSView; wxWindowCocoaHider *m_cocoaHider;
bool m_isInPaint; bool m_isInPaint;
static wxWindow *sm_capturedWindow; static wxWindow *sm_capturedWindow;
virtual void CocoaReplaceView(WX_NSView oldView, WX_NSView newView);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Implementation // Implementation
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@@ -17,6 +17,53 @@
#import <Appkit/NSView.h> #import <Appkit/NSView.h>
#import <AppKit/NSEvent.h> #import <AppKit/NSEvent.h>
// ========================================================================
// wxWindowCocoaHider
// ========================================================================
class wxWindowCocoaHider: protected wxCocoaNSView
{
DECLARE_NO_COPY_CLASS(wxWindowCocoaHider)
public:
wxWindowCocoaHider(wxWindow *owner);
virtual ~wxWindowCocoaHider();
inline WX_NSView GetNSView() { return m_dummyNSView; }
protected:
wxWindowCocoa *m_owner;
WX_NSView m_dummyNSView;
virtual void Cocoa_FrameChanged(void);
private:
wxWindowCocoaHider();
};
// ========================================================================
// wxWindowCocoaHider
// ========================================================================
wxWindowCocoaHider::wxWindowCocoaHider(wxWindow *owner)
: m_owner(owner)
{
wxASSERT(owner);
wxASSERT(owner->GetNSViewForHiding());
m_dummyNSView = [[NSView alloc]
initWithFrame:[owner->GetNSViewForHiding() frame]];
AssociateNSView(m_dummyNSView);
}
wxWindowCocoaHider::~wxWindowCocoaHider()
{
DisassociateNSView(m_dummyNSView);
[m_dummyNSView release];
}
void wxWindowCocoaHider::Cocoa_FrameChanged(void)
{
// Keep the real window in synch with the dummy
wxASSERT(m_dummyNSView);
[m_owner->GetNSViewForHiding() setFrame:[m_dummyNSView frame]];
}
// ========================================================================
// wxWindowCocoa
// ========================================================================
// normally the base classes aren't included, but wxWindow is special // normally the base classes aren't included, but wxWindow is special
#ifdef __WXUNIVERSAL__ #ifdef __WXUNIVERSAL__
IMPLEMENT_ABSTRACT_CLASS(wxWindowCocoa, wxWindowBase) IMPLEMENT_ABSTRACT_CLASS(wxWindowCocoa, wxWindowBase)
@@ -35,7 +82,7 @@ void wxWindowCocoa::Init()
InitBase(); InitBase();
m_cocoaNSView = NULL; m_cocoaNSView = NULL;
m_dummyNSView = NULL; m_cocoaHider = NULL;
m_isBeingDeleted = FALSE; m_isBeingDeleted = FALSE;
m_isInPaint = FALSE; m_isInPaint = FALSE;
} }
@@ -75,31 +122,22 @@ wxWindow::~wxWindow()
m_parent->RemoveChild(this); m_parent->RemoveChild(this);
CocoaRemoveFromParent(); CocoaRemoveFromParent();
delete m_cocoaHider;
SetNSView(NULL); SetNSView(NULL);
} }
void wxWindowCocoa::CocoaAddChild(wxWindowCocoa *child) void wxWindowCocoa::CocoaAddChild(wxWindowCocoa *child)
{ {
[m_cocoaNSView addSubview: child->m_cocoaNSView]; NSView *childView = child->GetNSViewForSuperview();
wxASSERT(!child->m_dummyNSView);
child->m_isShown = true; wxASSERT(childView);
[m_cocoaNSView addSubview: childView];
child->m_isShown = !m_cocoaHider;
} }
void wxWindowCocoa::CocoaRemoveFromParent(void) void wxWindowCocoa::CocoaRemoveFromParent(void)
{ {
if(m_dummyNSView) [GetNSViewForSuperview() removeFromSuperview];
{
wxASSERT(m_cocoaNSView);
// balances the replaceSubView:with:
[m_dummyNSView removeFromSuperview];
// But since we were the ones to alloc it
[m_dummyNSView release];
m_dummyNSView = nil;
// m_cocoaNSView has of course already been removed by virtue of
// replaceSubview: m_cocoaNSView with: m_dummyNSView
}
else
[m_cocoaNSView removeFromSuperview];
} }
void wxWindowCocoa::SetNSView(WX_NSView cocoaNSView) void wxWindowCocoa::SetNSView(WX_NSView cocoaNSView)
@@ -114,6 +152,18 @@ void wxWindowCocoa::SetNSView(WX_NSView cocoaNSView)
if(need_debug) wxLogDebug("wxWindowCocoa=%p::SetNSView [cocoaNSView=%p retainCount]=%d",this,cocoaNSView,[cocoaNSView retainCount]); if(need_debug) wxLogDebug("wxWindowCocoa=%p::SetNSView [cocoaNSView=%p retainCount]=%d",this,cocoaNSView,[cocoaNSView retainCount]);
} }
WX_NSView wxWindowCocoa::GetNSViewForSuperview() const
{
return m_cocoaHider
? m_cocoaHider->GetNSView()
: m_cocoaNSView;
}
WX_NSView wxWindowCocoa::GetNSViewForHiding() const
{
return m_cocoaNSView;
}
bool wxWindowCocoa::Cocoa_drawRect(const NSRect &rect) bool wxWindowCocoa::Cocoa_drawRect(const NSRect &rect)
{ {
wxLogDebug("Cocoa_drawRect"); wxLogDebug("Cocoa_drawRect");
@@ -136,10 +186,9 @@ bool wxWindowCocoa::Cocoa_drawRect(const NSRect &rect)
void wxWindowCocoa::InitMouseEvent(wxMouseEvent& event, WX_NSEvent cocoaEvent) void wxWindowCocoa::InitMouseEvent(wxMouseEvent& event, WX_NSEvent cocoaEvent)
{ {
NSView *nsview = m_dummyNSView?m_dummyNSView:m_cocoaNSView; wxASSERT_MSG([m_cocoaNSView window]==[cocoaEvent window],"Mouse event for different NSWindow");
wxASSERT_MSG([nsview window]==[cocoaEvent window],"Mouse event for different NSWindow"); NSPoint cocoaPoint = [m_cocoaNSView convertPoint:[(NSEvent*)cocoaEvent locationInWindow] fromView:nil];
NSPoint cocoaPoint = [nsview convertPoint:[(NSEvent*)cocoaEvent locationInWindow] fromView:nil]; NSRect cocoaRect = [m_cocoaNSView frame];
NSRect cocoaRect = [nsview frame];
const wxPoint &clientorigin = GetClientAreaOrigin(); const wxPoint &clientorigin = GetClientAreaOrigin();
event.m_x = (wxCoord)cocoaPoint.x - clientorigin.x; event.m_x = (wxCoord)cocoaPoint.x - clientorigin.x;
event.m_y = (wxCoord)(cocoaRect.size.height - cocoaPoint.y) - clientorigin.y; event.m_y = (wxCoord)(cocoaRect.size.height - cocoaPoint.y) - clientorigin.y;
@@ -240,6 +289,11 @@ bool wxWindow::Close(bool force)
return false; return false;
} }
void wxWindow::CocoaReplaceView(WX_NSView oldView, WX_NSView newView)
{
[[oldView superview] replaceSubview:oldView with:newView];
}
bool wxWindow::Show(bool show) bool wxWindow::Show(bool show)
{ {
wxAutoNSAutoreleasePool pool; wxAutoNSAutoreleasePool pool;
@@ -248,34 +302,32 @@ bool wxWindow::Show(bool show)
// wxSpinCtrl (generic) abuses m_isShown, don't use it for any logic // wxSpinCtrl (generic) abuses m_isShown, don't use it for any logic
// wxASSERT_MSG( (m_isShown && !m_dummyNSView) || (!m_isShown && m_dummyNSView),"wxWindow: m_isShown does not agree with m_dummyNSView"); // wxASSERT_MSG( (m_isShown && !m_dummyNSView) || (!m_isShown && m_dummyNSView),"wxWindow: m_isShown does not agree with m_dummyNSView");
// Return false if there isn't a window to show or hide // Return false if there isn't a window to show or hide
if(!m_cocoaNSView) NSView *cocoaView = GetNSViewForHiding();
if(!cocoaView)
return false; return false;
if(show) if(show)
{ {
// If state isn't changing, return false // If state isn't changing, return false
if(!m_dummyNSView) if(!m_cocoaHider)
return false; return false;
// replaceSubView:with: releases m_dummyNSView, balancing the CocoaReplaceView(m_cocoaHider->GetNSView(), cocoaView);
// previous replaceSubView:with wxASSERT(![m_cocoaHider->GetNSView() superview]);
[[m_dummyNSView superview] replaceSubview:m_dummyNSView with:m_cocoaNSView]; delete m_cocoaHider;
wxASSERT(![m_dummyNSView superview]); m_cocoaHider = NULL;
// But since we were the ones to alloc it wxASSERT([cocoaView superview]);
[m_dummyNSView release];
m_dummyNSView = nil;
wxASSERT([m_cocoaNSView superview]);
} }
else else
{ {
// If state isn't changing, return false // If state isn't changing, return false
if(m_dummyNSView) if(m_cocoaHider)
return false; return false;
m_dummyNSView = [[NSView alloc] initWithFrame: [m_cocoaNSView frame]]; m_cocoaHider = new wxWindowCocoaHider(this);
// NOTE: replaceSubView will cause m_cocaNSView to be (auto)released // NOTE: replaceSubview:with will cause m_cocaNSView to be
// which balances out addSubView // (auto)released which balances out addSubview
[[m_cocoaNSView superview] replaceSubview:m_cocoaNSView with:m_dummyNSView]; CocoaReplaceView(cocoaView, m_cocoaHider->GetNSView());
// m_coocaNSView is now only retained by us // m_coocaNSView is now only retained by us
wxASSERT([m_dummyNSView superview]); wxASSERT([m_cocoaHider->GetNSView() superview]);
wxASSERT(![m_cocoaNSView superview]); wxASSERT(![cocoaView superview]);
} }
m_isShown = show; m_isShown = show;
return true; return true;
@@ -325,22 +377,19 @@ void wxWindowCocoa::DoMoveWindow(int x, int y, int width, int height)
{ {
// wxLogDebug("wxWindow=%p::DoMoveWindow(%d,%d,%d,%d)",this,x,y,width,height); // wxLogDebug("wxWindow=%p::DoMoveWindow(%d,%d,%d,%d)",this,x,y,width,height);
NSView *nsview = m_dummyNSView?m_dummyNSView:m_cocoaNSView; NSView *nsview = GetNSViewForSuperview();
NSView *superview = [nsview superview]; NSView *superview = [nsview superview];
wxCHECK_RET(superview,"NSView does not have a superview"); wxCHECK_RET(superview,"NSView does not have a superview");
NSRect parentRect = [superview frame]; NSRect parentRect = [superview frame];
NSRect cocoaRect = NSMakeRect(x,parentRect.size.height-(y+height),width,height); NSRect cocoaRect = NSMakeRect(x,parentRect.size.height-(y+height),width,height);
[m_cocoaNSView setFrame: cocoaRect]; [nsview setFrame: cocoaRect];
// Also change the dummy's size
if(m_dummyNSView)
[m_dummyNSView setFrame: cocoaRect];
} }
// Get total size // Get total size
void wxWindow::DoGetSize(int *w, int *h) const void wxWindow::DoGetSize(int *w, int *h) const
{ {
NSRect cocoaRect = [m_cocoaNSView frame]; NSRect cocoaRect = [GetNSViewForSuperview() frame];
if(w) if(w)
*w=(int)cocoaRect.size.width; *w=(int)cocoaRect.size.width;
if(h) if(h)
@@ -350,7 +399,7 @@ void wxWindow::DoGetSize(int *w, int *h) const
void wxWindow::DoGetPosition(int *x, int *y) const void wxWindow::DoGetPosition(int *x, int *y) const
{ {
NSView *nsview = m_dummyNSView?m_dummyNSView:m_cocoaNSView; NSView *nsview = GetNSViewForSuperview();
NSView *superview = [nsview superview]; NSView *superview = [nsview superview];
wxCHECK_RET(superview,"NSView does not have a superview"); wxCHECK_RET(superview,"NSView does not have a superview");
NSRect parentRect = [superview frame]; NSRect parentRect = [superview frame];
@@ -491,7 +540,7 @@ void wxWindow::Clear()
void wxWindow::Raise() void wxWindow::Raise()
{ {
wxAutoNSAutoreleasePool pool; wxAutoNSAutoreleasePool pool;
NSView *nsview = m_dummyNSView?m_dummyNSView:m_cocoaNSView; NSView *nsview = GetNSViewForSuperview();
NSView *superview = [nsview superview]; NSView *superview = [nsview superview];
[nsview removeFromSuperview]; [nsview removeFromSuperview];
[superview addSubview:nsview]; [superview addSubview:nsview];