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:
@@ -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
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@@ -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];
|
||||||
|
Reference in New Issue
Block a user