+/////////////////////////////////////////////////////////////////////////////
+// Name: cocoa/notebook.mm
+// Purpose: wxNotebook
+// Author: David Elliott
+// Modified by:
+// Created: 2004/04/08
+// RCS-ID: $Id$
+// Copyright: (c) 2004 David Elliott
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#include "wx/wxprec.h"
+#ifndef WX_PRECOMP
+ #include "wx/app.h"
+ #include "wx/notebook.h"
+#endif //WX_PRECOMP
+#include "wx/imaglist.h"
+
+#include "wx/cocoa/autorelease.h"
+#include "wx/cocoa/string.h"
+
+#import <AppKit/NSTabView.h>
+#import <AppKit/NSTabViewItem.h>
+#import <AppKit/NSImage.h>
+
+// testing:
+#import <AppKit/NSPasteboard.h>
+#import <Foundation/NSArray.h>
+
+// ========================================================================
+// WXCTabViewImageItem
+// ========================================================================
+@interface WXCTabViewImageItem : NSTabViewItem
+{
+ NSImage *m_image;
+}
+
+- (id)init;
+- (id)initWithIdentifier: (id)identifier;
+- (void)dealloc;
+
+- (NSSize)sizeOfLabel:(BOOL)shouldTruncateLabel;
+- (void)drawLabel:(BOOL)shouldTruncateLabel inRect:(NSRect)tabRect;
+
+- (NSImage*)image;
+- (void)setImage:(NSImage*)image;
+@end // interface WXCTabViewImageItem : NSTabViewItem
+
+@implementation WXCTabViewImageItem : NSTabViewItem
+- (id)init
+{
+ return [self initWithIdentifier:nil];
+}
+
+- (id)initWithIdentifier: (id)identifier;
+{
+ m_image = nil;
+ return [super initWithIdentifier:identifier];
+}
+
+- (void)dealloc
+{
+ [m_image release];
+}
+
+- (NSSize)sizeOfLabel:(BOOL)shouldTruncateLabel
+{
+ NSSize labelSize = [super sizeOfLabel:shouldTruncateLabel];
+ if(!m_image)
+ return labelSize;
+ NSSize imageSize = [m_image size];
+ // scale image size
+ if(imageSize.height > labelSize.height)
+ {
+ imageSize.width *= labelSize.height/imageSize.height;
+ imageSize.height *= labelSize.height/imageSize.height;
+ [m_image setScalesWhenResized:YES];
+ [m_image setSize: imageSize];
+ }
+ labelSize.width += imageSize.width;
+ return labelSize;
+}
+
+- (void)drawLabel:(BOOL)shouldTruncateLabel inRect:(NSRect)tabRect
+{
+ if(m_image)
+ {
+ NSSize imageSize = [m_image size];
+ [m_image compositeToPoint:NSMakePoint(tabRect.origin.x,
+ tabRect.origin.y+imageSize.height)
+ operation:NSCompositeSourceOver];
+ tabRect.size.width -= imageSize.width;
+ tabRect.origin.x += imageSize.width;
+ }
+ [super drawLabel:shouldTruncateLabel inRect:tabRect];
+}
+
+- (NSImage*)image
+{
+ return m_image;
+}
+
+- (void)setImage:(NSImage*)image
+{
+ [image retain];
+ [m_image release];
+ m_image = image;
+ if(!m_image)
+ return;
+ [[NSPasteboard generalPasteboard]
+ declareTypes:[NSArray arrayWithObject:NSTIFFPboardType]
+ owner:nil];
+ [[NSPasteboard generalPasteboard]
+ setData:[m_image TIFFRepresentation]
+ forType:NSTIFFPboardType];
+}
+
+@end // implementation WXCTabViewImageItem : NSTabViewItem
+
+// ========================================================================
+// wxNotebookEvent
+// ========================================================================
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING)
+IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxNotifyEvent)
+
+// ========================================================================
+// wxNotebook
+// ========================================================================
+IMPLEMENT_DYNAMIC_CLASS(wxNotebook, wxControl)
+BEGIN_EVENT_TABLE(wxNotebook, wxNotebookBase)
+END_EVENT_TABLE()
+WX_IMPLEMENT_COCOA_OWNER(wxNotebook,NSTabView,NSView,NSView)
+
+bool wxNotebook::Create(wxWindow *parent, wxWindowID winid,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name)
+{
+ wxAutoNSAutoreleasePool pool;
+ if(!CreateControl(parent,winid,pos,size,style,wxDefaultValidator,name))
+ return false;
+ m_cocoaNSView = NULL;
+ SetNSTabView([[NSTabView alloc] initWithFrame:MakeDefaultNSRect(size)]);
+ if(m_parent)
+ m_parent->CocoaAddChild(this);
+ SetInitialFrameRect(pos,size);
+
+ return true;
+}
+
+wxNotebook::~wxNotebook()
+{
+}
+
+void wxNotebook::SetPadding(const wxSize& padding)
+{ // Can't do
+}
+
+void wxNotebook::SetTabSize(const wxSize& sz)
+{ // Can't do
+}
+
+void wxNotebook::SetPageSize(const wxSize& size)
+{
+}
+
+
+wxNotebookPage *wxNotebook::DoRemovePage(size_t nPage)
+{
+ wxNotebookPage *page = wxNotebookBase::DoRemovePage(nPage);
+ if(!page)
+ return NULL;
+ NSTabViewItem *tvitem = [GetNSTabView() tabViewItemAtIndex: nPage];
+ wxASSERT(tvitem);
+ [tvitem retain];
+ [GetNSTabView() removeTabViewItem:tvitem];
+ // Remove the child window as a notebook page
+ wxASSERT([tvitem view] == page->GetNSViewForSuperview());
+ [tvitem setView:nil];
+ [tvitem release];
+ // Make it back into a normal child window
+ [m_cocoaNSView addSubview: page->GetNSViewForSuperview()];
+
+ return page;
+}
+
+bool wxNotebook::DeletePage(size_t nPage)
+{
+ return wxNotebookBase::DeletePage(nPage);
+}
+
+bool wxNotebook::InsertPage( size_t pos,
+ wxNotebookPage *page, const wxString& title,
+ bool bSelect, int imageId)
+{
+ wxAutoNSAutoreleasePool pool;
+ m_pages.Insert(page,pos);
+ NSTabViewItem *tvitem = [[WXCTabViewImageItem alloc] initWithIdentifier:nil];
+ [tvitem setLabel: wxNSStringWithWxString(title)];
+ const wxBitmap *bmp = (imageId!=-1)?m_imageList->GetBitmap(imageId):NULL;
+ if(bmp)
+ [(WXCTabViewImageItem*) tvitem setImage: bmp->GetNSImage(true)];
+
+ NSView *pageNSView = page->GetNSViewForSuperview();
+ // Remove it as a normal child
+ wxASSERT(m_cocoaNSView == [pageNSView superview]);
+ [pageNSView removeFromSuperview];
+ // And make it a notebook page
+ [tvitem setView: pageNSView];
+
+ [GetNSTabView() insertTabViewItem:tvitem atIndex:pos];
+ [tvitem release];
+
+ return true;
+}
+
+bool wxNotebook::DeleteAllPages()
+{
+ while(!m_pages.IsEmpty())
+ DeletePage(0);
+ return true;
+}
+
+
+bool wxNotebook::SetPageText(size_t nPage, const wxString& title)
+{
+ NSTabViewItem *tvitem = [GetNSTabView() tabViewItemAtIndex: nPage];
+ if(!tvitem)
+ return false;
+ [tvitem setLabel: wxNSStringWithWxString(title)];
+ return true;
+}
+
+wxString wxNotebook::GetPageText(size_t nPage) const
+{
+ return wxStringWithNSString([[GetNSTabView() tabViewItemAtIndex: nPage] label]);
+}
+
+
+int wxNotebook::GetPageImage(size_t nPage) const
+{
+ // To do this we'd need to keep track of this, which we don't!
+ return -1;
+}
+
+bool wxNotebook::SetPageImage(size_t nPage, int nImage)
+{
+ const wxBitmap *bmp = nImage!=-1?m_imageList->GetBitmap(nImage):NULL;
+ if(!bmp)
+ return false;
+ NSTabViewItem *tvitem = [GetNSTabView() tabViewItemAtIndex: nPage];
+ if(!tvitem)
+ return false;
+ [(WXCTabViewImageItem*) tvitem setImage: bmp->GetNSImage(true)];
+ return true;
+}
+
+
+int wxNotebook::SetSelection(size_t nPage)
+{
+ [GetNSTabView() selectTabViewItemAtIndex:nPage];
+ return GetSelection();
+}
+
+int wxNotebook::GetSelection() const
+{
+ NSTabViewItem *selectedItem = [GetNSTabView() selectedTabViewItem];
+ if(!selectedItem)
+ return -1;
+ return [GetNSTabView() indexOfTabViewItem:selectedItem];
+}
+
+void wxNotebook::CocoaDelegate_tabView_didSelectTabViewItem(WX_NSTabViewItem tabViewItem)
+{
+ // FIXME: oldSel probably == newSel
+ wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, GetId(),
+ [GetNSTabView() indexOfTabViewItem:tabViewItem], GetSelection());
+ event.SetEventObject(this);
+}
+
+bool wxNotebook::CocoaDelegate_tabView_shouldSelectTabViewItem(WX_NSTabViewItem tabViewItem)
+{
+ wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, GetId(),
+ [GetNSTabView() indexOfTabViewItem:tabViewItem], GetSelection());
+ event.SetEventObject(this);
+ return !GetEventHandler()->ProcessEvent(event) || event.IsAllowed();
+}
+