1 /////////////////////////////////////////////////////////////////////////////
 
   2 // Name:        cocoa/notebook.mm
 
   4 // Author:      David Elliott
 
   8 // Copyright:   (c) 2004 David Elliott
 
   9 // Licence:     wxWidgets licence
 
  10 /////////////////////////////////////////////////////////////////////////////
 
  12 #include "wx/wxprec.h"
 
  19 #include "wx/notebook.h"
 
  20 #include "wx/imaglist.h"
 
  22 #include "wx/cocoa/autorelease.h"
 
  23 #include "wx/cocoa/string.h"
 
  24 #include "wx/cocoa/objc/objc_uniquifying.h"
 
  26 #import <AppKit/NSTabView.h>
 
  27 #import <AppKit/NSTabViewItem.h>
 
  28 #import <AppKit/NSImage.h>
 
  31 #import <AppKit/NSPasteboard.h>
 
  32 #import <Foundation/NSArray.h>
 
  34 // ========================================================================
 
  35 // WXCTabViewImageItem
 
  36 // ========================================================================
 
  37 @interface WXCTabViewImageItem : NSTabViewItem
 
  43 - (id)initWithIdentifier: (id)identifier;
 
  46 - (NSSize)sizeOfLabel:(BOOL)shouldTruncateLabel;
 
  47 - (void)drawLabel:(BOOL)shouldTruncateLabel inRect:(NSRect)tabRect;
 
  50 - (void)setImage:(NSImage*)image;
 
  51 @end // interface WXCTabViewImageItem : NSTabViewItem
 
  52 WX_DECLARE_GET_OBJC_CLASS(WXCTabViewImageItem,NSTabViewItem)
 
  54 @implementation WXCTabViewImageItem : NSTabViewItem
 
  57     return [self initWithIdentifier:nil];
 
  60 - (id)initWithIdentifier: (id)identifier;
 
  63     return [super initWithIdentifier:identifier];
 
  72 - (NSSize)sizeOfLabel:(BOOL)shouldTruncateLabel
 
  74     NSSize labelSize = [super sizeOfLabel:shouldTruncateLabel];
 
  77     NSSize imageSize = [m_image size];
 
  79     if(imageSize.height > labelSize.height)
 
  81         imageSize.width *= labelSize.height/imageSize.height;
 
  82         imageSize.height *= labelSize.height/imageSize.height;
 
  83         [m_image setScalesWhenResized:YES];
 
  84         [m_image setSize: imageSize];
 
  86     labelSize.width += imageSize.width;
 
  90 - (void)drawLabel:(BOOL)shouldTruncateLabel inRect:(NSRect)tabRect
 
  94         NSSize imageSize = [m_image size];
 
  95         [m_image compositeToPoint:NSMakePoint(tabRect.origin.x,
 
  96                 tabRect.origin.y+imageSize.height)
 
  97             operation:NSCompositeSourceOver];
 
  98         tabRect.size.width -= imageSize.width;
 
  99         tabRect.origin.x += imageSize.width;
 
 101     [super drawLabel:shouldTruncateLabel inRect:tabRect];
 
 109 - (void)setImage:(NSImage*)image
 
 116     [[NSPasteboard generalPasteboard]
 
 117         declareTypes:[NSArray arrayWithObject:NSTIFFPboardType]
 
 119     [[NSPasteboard generalPasteboard]
 
 120         setData:[m_image TIFFRepresentation]
 
 121         forType:NSTIFFPboardType];
 
 124 @end // implementation WXCTabViewImageItem : NSTabViewItem
 
 125 WX_IMPLEMENT_GET_OBJC_CLASS(WXCTabViewImageItem,NSTabViewItem)
 
 127 // ========================================================================
 
 129 // ========================================================================
 
 130 DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED)
 
 131 DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING)
 
 132 IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxNotifyEvent)
 
 134 // ========================================================================
 
 136 // ========================================================================
 
 137 IMPLEMENT_DYNAMIC_CLASS(wxNotebook, wxBookCtrlBase)
 
 138 BEGIN_EVENT_TABLE(wxNotebook, wxNotebookBase)
 
 140 WX_IMPLEMENT_COCOA_OWNER(wxNotebook,NSTabView,NSView,NSView)
 
 142 bool wxNotebook::Create(wxWindow *parent, wxWindowID winid,
 
 146            const wxString& name)
 
 148     wxAutoNSAutoreleasePool pool;
 
 149     if(!CreateControl(parent,winid,pos,size,style,wxDefaultValidator,name))
 
 151     m_cocoaNSView = NULL;
 
 152     SetNSTabView([[NSTabView alloc] initWithFrame:MakeDefaultNSRect(size)]);
 
 156         NSTabViewType tabViewType;
 
 158             tabViewType = NSTopTabsBezelBorder;
 
 159         else if(style & wxNB_LEFT)
 
 160             tabViewType = NSLeftTabsBezelBorder;
 
 161         else if(style & wxNB_RIGHT)
 
 162             tabViewType = NSRightTabsBezelBorder;
 
 163         else if(style & wxNB_BOTTOM)
 
 164             tabViewType = NSBottomTabsBezelBorder;
 
 167         [GetNSTabView() setTabViewType:tabViewType];
 
 171         m_parent->CocoaAddChild(this);
 
 172     SetInitialFrameRect(pos,size);
 
 177 wxNotebook::~wxNotebook()
 
 181 void wxNotebook::SetPadding(const wxSize& padding)
 
 185 void wxNotebook::SetTabSize(const wxSize& sz)
 
 189 void wxNotebook::SetPageSize(const wxSize& size)
 
 194 wxNotebookPage *wxNotebook::DoRemovePage(size_t nPage)
 
 196     wxNotebookPage *page = wxNotebookBase::DoRemovePage(nPage);
 
 199     NSTabViewItem *tvitem = [GetNSTabView() tabViewItemAtIndex: nPage];
 
 202     [GetNSTabView() removeTabViewItem:tvitem];
 
 203     // Remove the child window as a notebook page
 
 204     wxASSERT(static_cast<NSView*>([tvitem view]) == page->GetNSViewForSuperview());
 
 205     [tvitem setView:nil];
 
 207     // Make it back into a normal child window
 
 208     [m_cocoaNSView addSubview: page->GetNSViewForSuperview()];
 
 213 bool wxNotebook::DeletePage(size_t nPage)
 
 215     return wxNotebookBase::DeletePage(nPage);
 
 218 bool wxNotebook::InsertPage( size_t pos,
 
 219                  wxNotebookPage *page, const wxString& title,
 
 220                  bool bSelect, int imageId)
 
 222     wxAutoNSAutoreleasePool pool;
 
 223     m_pages.Insert(page,pos);
 
 224     NSTabViewItem *tvitem = [[WX_GET_OBJC_CLASS(WXCTabViewImageItem) alloc] initWithIdentifier:nil];
 
 225     [tvitem setLabel: wxNSStringWithWxString(title)];
 
 226     const wxBitmap *bmp = (imageId!=-1)?m_imageList->GetBitmapPtr(imageId):NULL;
 
 228         [(WXCTabViewImageItem*) tvitem setImage: bmp->GetNSImage(true)];
 
 230     NSView *pageNSView = page->GetNSViewForSuperview();
 
 231     // Remove it as a normal child
 
 232     wxASSERT(m_cocoaNSView == [pageNSView superview]);
 
 233     [pageNSView removeFromSuperview];
 
 234     // And make it a notebook page
 
 235     [tvitem setView: pageNSView];
 
 237     [GetNSTabView() insertTabViewItem:tvitem atIndex:pos];
 
 243 bool wxNotebook::DeleteAllPages()
 
 245     while(!m_pages.IsEmpty())
 
 251 bool wxNotebook::SetPageText(size_t nPage, const wxString& title)
 
 253     NSTabViewItem *tvitem = [GetNSTabView() tabViewItemAtIndex: nPage];
 
 256     [tvitem setLabel: wxNSStringWithWxString(title)];
 
 260 wxString wxNotebook::GetPageText(size_t nPage) const
 
 262     return wxStringWithNSString([[GetNSTabView() tabViewItemAtIndex: nPage] label]);
 
 266 int wxNotebook::GetPageImage(size_t nPage) const
 
 268     // To do this we'd need to keep track of this, which we don't!
 
 272 bool wxNotebook::SetPageImage(size_t nPage, int nImage)
 
 274     const wxBitmap *bmp = nImage!=-1?m_imageList->GetBitmapPtr(nImage):NULL;
 
 277     NSTabViewItem *tvitem = [GetNSTabView() tabViewItemAtIndex: nPage];
 
 280     [(WXCTabViewImageItem*) tvitem setImage: bmp->GetNSImage(true)];
 
 284 int wxNotebook::SetSelection(size_t nPage)
 
 286     const int pageOld = GetSelection();
 
 288     if ( !SendPageChangingEvent(nPage) )
 
 291     int page = ChangeSelection(nPage);
 
 292     if ( page != wxNOT_FOUND )
 
 294         SendPageChangedEvent(pageOld);
 
 300 int wxNotebook::ChangeSelection(size_t nPage)
 
 302     wxAutoNSAutoreleasePool pool;
 
 303     [GetNSTabView() selectTabViewItemAtIndex:nPage];
 
 304     return GetSelection();
 
 307 int wxNotebook::GetSelection() const
 
 309     NSTabViewItem *selectedItem = [GetNSTabView() selectedTabViewItem];
 
 312     return [GetNSTabView() indexOfTabViewItem:selectedItem];
 
 315 void wxNotebook::CocoaDelegate_tabView_didSelectTabViewItem(WX_NSTabViewItem tabViewItem)
 
 317     // FIXME: oldSel probably == newSel
 
 318     wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, GetId(),
 
 319         [GetNSTabView() indexOfTabViewItem:tabViewItem], GetSelection());
 
 320     event.SetEventObject(this);
 
 321     GetEventHandler()->ProcessEvent(event);
 
 324 bool wxNotebook::CocoaDelegate_tabView_shouldSelectTabViewItem(WX_NSTabViewItem tabViewItem)
 
 326     wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, GetId(),
 
 327         [GetNSTabView() indexOfTabViewItem:tabViewItem], GetSelection());
 
 328     event.SetEventObject(this);
 
 329     return !HandleWindowEvent(event) || event.IsAllowed();
 
 332 #endif // wxUSE_NOTEBOOK