#import <Appkit/NSView.h>
#import <AppKit/NSEvent.h>
+#import <AppKit/NSScrollView.h>
+#import <AppKit/NSColor.h>
+#import <AppKit/NSClipView.h>
// ========================================================================
// wxWindowCocoaHider
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
// ========================================================================
[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
// ========================================================================
m_cocoaNSView = NULL;
m_cocoaHider = NULL;
+ m_cocoaScroller = NULL;
m_isBeingDeleted = FALSE;
m_isInPaint = FALSE;
}
return false;
// TODO: create the window
- NSRect cocoaRect = NSMakeRect(10,10,20,20);
m_cocoaNSView = NULL;
- SetNSView([[NSView alloc] initWithFrame: cocoaRect]);
+ SetNSView([[NSView alloc] initWithFrame: MakeDefaultNSRect(size)]);
[m_cocoaNSView release];
if (m_parent)
m_parent->AddChild(this);
m_parent->CocoaAddChild(this);
}
+ SetInitialFrameRect(pos,size);
return TRUE;
}
CocoaRemoveFromParent();
delete m_cocoaHider;
+ delete m_cocoaScroller;
SetNSView(NULL);
}
{
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)
[nsview setFrame: cocoaRect];
}
+void wxWindowCocoa::SetInitialFrameRect(const wxPoint& pos, const wxSize& size)
+{
+ NSView *nsview = GetNSViewForSuperview();
+ NSView *superview = [nsview superview];
+ wxCHECK_RET(superview,"NSView does not have a superview");
+ NSRect parentRect = [superview frame];
+ NSRect frameRect = [nsview frame];
+ if(size.x!=-1)
+ frameRect.size.width = size.x;
+ if(size.y!=-1)
+ frameRect.size.height = size.y;
+ frameRect.origin.x = pos.x;
+ frameRect.origin.y = parentRect.size.height-(pos.y+size.y);
+ [nsview setFrame: frameRect];
+}
+
// Get total size
void wxWindow::DoGetSize(int *w, int *h) 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)
{
wxLogDebug("DoSetClientSize=(%d,%d)",width,height);
- // TODO
+ if(m_cocoaScroller)
+ m_cocoaScroller->ClientSizeToSize(width,height);
+ CocoaSetWxWindowSize(width,height);
+}
+
+void wxWindow::CocoaSetWxWindowSize(int width, int height)
+{
+ wxWindowCocoa::DoSetSize(-1,-1,width,height,wxSIZE_USE_EXISTING);
}
int wxWindow::GetCharHeight() const
// 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)
{
+ CocoaCreateNSScrollView();
// TODO
}
// 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
return TRUE;
}
-void wxWindow::Clear()
+static int CocoaRaiseWindowCompareFunction(id first, id second, void *target)
{
- // TODO
+ // first should be ordered higher
+ if(first==target)
+ return NSOrderedDescending;
+ // second should be ordered higher
+ if(second==target)
+ return NSOrderedAscending;
+ return NSOrderedSame;
}
// Raise the window to the top of the Z order
void wxWindow::Raise()
{
- wxAutoNSAutoreleasePool pool;
+// wxAutoNSAutoreleasePool pool;
NSView *nsview = GetNSViewForSuperview();
- NSView *superview = [nsview superview];
- [nsview removeFromSuperview];
- [superview addSubview:nsview];
+ [[nsview superview] sortSubviewsUsingFunction:
+ CocoaRaiseWindowCompareFunction
+ context: nsview];
+}
+
+static int CocoaLowerWindowCompareFunction(id first, id second, void *target)
+{
+ // first should be ordered lower
+ if(first==target)
+ return NSOrderedAscending;
+ // second should be ordered lower
+ if(second==target)
+ return NSOrderedDescending;
+ return NSOrderedSame;
}
// Lower the window to the bottom of the Z order
void wxWindow::Lower()
{
- // TODO
+ NSView *nsview = GetNSViewForSuperview();
+ [[nsview superview] sortSubviewsUsingFunction:
+ CocoaLowerWindowCompareFunction
+ context: nsview];
}
bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)