1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/cocoa/notebook.mm
4 // Author: David Elliott
7 // Copyright: (c) 2004 David Elliott
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 #include "wx/wxprec.h"
18 #include "wx/notebook.h"
19 #include "wx/imaglist.h"
21 #include "wx/cocoa/autorelease.h"
22 #include "wx/cocoa/string.h"
23 #include "wx/cocoa/objc/objc_uniquifying.h"
25 #import <AppKit/NSTabView.h>
26 #import <AppKit/NSTabViewItem.h>
27 #import <AppKit/NSImage.h>
30 #import <AppKit/NSPasteboard.h>
31 #import <Foundation/NSArray.h>
33 // ========================================================================
34 // WXCTabViewImageItem
35 // ========================================================================
36 @interface WXCTabViewImageItem : NSTabViewItem
42 - (id)initWithIdentifier: (id)identifier;
45 - (NSSize)sizeOfLabel:(BOOL)shouldTruncateLabel;
46 - (void)drawLabel:(BOOL)shouldTruncateLabel inRect:(NSRect)tabRect;
49 - (void)setImage:(NSImage*)image;
50 @end // interface WXCTabViewImageItem : NSTabViewItem
51 WX_DECLARE_GET_OBJC_CLASS(WXCTabViewImageItem,NSTabViewItem)
53 @implementation WXCTabViewImageItem : NSTabViewItem
56 return [self initWithIdentifier:nil];
59 - (id)initWithIdentifier: (id)identifier;
62 return [super initWithIdentifier:identifier];
71 - (NSSize)sizeOfLabel:(BOOL)shouldTruncateLabel
73 NSSize labelSize = [super sizeOfLabel:shouldTruncateLabel];
76 NSSize imageSize = [m_image size];
78 if(imageSize.height > labelSize.height)
80 imageSize.width *= labelSize.height/imageSize.height;
81 imageSize.height *= labelSize.height/imageSize.height;
82 [m_image setScalesWhenResized:YES];
83 [m_image setSize: imageSize];
85 labelSize.width += imageSize.width;
89 - (void)drawLabel:(BOOL)shouldTruncateLabel inRect:(NSRect)tabRect
93 NSSize imageSize = [m_image size];
94 [m_image compositeToPoint:NSMakePoint(tabRect.origin.x,
95 tabRect.origin.y+imageSize.height)
96 operation:NSCompositeSourceOver];
97 tabRect.size.width -= imageSize.width;
98 tabRect.origin.x += imageSize.width;
100 [super drawLabel:shouldTruncateLabel inRect:tabRect];
108 - (void)setImage:(NSImage*)image
115 [[NSPasteboard generalPasteboard]
116 declareTypes:[NSArray arrayWithObject:NSTIFFPboardType]
118 [[NSPasteboard generalPasteboard]
119 setData:[m_image TIFFRepresentation]
120 forType:NSTIFFPboardType];
123 @end // implementation WXCTabViewImageItem : NSTabViewItem
124 WX_IMPLEMENT_GET_OBJC_CLASS(WXCTabViewImageItem,NSTabViewItem)
126 // ========================================================================
128 // ========================================================================
130 BEGIN_EVENT_TABLE(wxNotebook, wxNotebookBase)
132 WX_IMPLEMENT_COCOA_OWNER(wxNotebook,NSTabView,NSView,NSView)
134 bool wxNotebook::Create(wxWindow *parent, wxWindowID winid,
138 const wxString& name)
140 wxAutoNSAutoreleasePool pool;
141 if(!CreateControl(parent,winid,pos,size,style,wxDefaultValidator,name))
143 m_cocoaNSView = NULL;
144 SetNSTabView([[NSTabView alloc] initWithFrame:MakeDefaultNSRect(size)]);
148 NSTabViewType tabViewType;
150 tabViewType = NSTopTabsBezelBorder;
151 else if(style & wxNB_LEFT)
152 tabViewType = NSLeftTabsBezelBorder;
153 else if(style & wxNB_RIGHT)
154 tabViewType = NSRightTabsBezelBorder;
155 else if(style & wxNB_BOTTOM)
156 tabViewType = NSBottomTabsBezelBorder;
159 [GetNSTabView() setTabViewType:tabViewType];
163 m_parent->CocoaAddChild(this);
164 SetInitialFrameRect(pos,size);
169 wxNotebook::~wxNotebook()
173 void wxNotebook::SetPadding(const wxSize& padding)
177 void wxNotebook::SetTabSize(const wxSize& sz)
181 void wxNotebook::SetPageSize(const wxSize& size)
186 wxNotebookPage *wxNotebook::DoRemovePage(size_t nPage)
188 wxNotebookPage *page = wxNotebookBase::DoRemovePage(nPage);
191 NSTabViewItem *tvitem = [GetNSTabView() tabViewItemAtIndex: nPage];
194 [GetNSTabView() removeTabViewItem:tvitem];
195 // Remove the child window as a notebook page
196 wxASSERT(static_cast<NSView*>([tvitem view]) == page->GetNSViewForSuperview());
197 [tvitem setView:nil];
199 // Make it back into a normal child window
200 [m_cocoaNSView addSubview: page->GetNSViewForSuperview()];
205 bool wxNotebook::DeletePage(size_t nPage)
207 return wxNotebookBase::DeletePage(nPage);
210 bool wxNotebook::InsertPage( size_t pos,
211 wxNotebookPage *page, const wxString& title,
212 bool bSelect, int imageId)
214 wxAutoNSAutoreleasePool pool;
215 m_pages.Insert(page,pos);
216 NSTabViewItem *tvitem = [[WX_GET_OBJC_CLASS(WXCTabViewImageItem) alloc] initWithIdentifier:nil];
217 [tvitem setLabel: wxNSStringWithWxString(title)];
218 const wxBitmap *bmp = (imageId!=-1)?m_imageList->GetBitmapPtr(imageId):NULL;
220 [(WXCTabViewImageItem*) tvitem setImage: bmp->GetNSImage(true)];
222 NSView *pageNSView = page->GetNSViewForSuperview();
223 // Remove it as a normal child
224 wxASSERT(m_cocoaNSView == [pageNSView superview]);
225 [pageNSView removeFromSuperview];
226 // And make it a notebook page
227 [tvitem setView: pageNSView];
229 [GetNSTabView() insertTabViewItem:tvitem atIndex:pos];
235 bool wxNotebook::DeleteAllPages()
237 while(!m_pages.IsEmpty())
243 bool wxNotebook::SetPageText(size_t nPage, const wxString& title)
245 NSTabViewItem *tvitem = [GetNSTabView() tabViewItemAtIndex: nPage];
248 [tvitem setLabel: wxNSStringWithWxString(title)];
252 wxString wxNotebook::GetPageText(size_t nPage) const
254 return wxStringWithNSString([[GetNSTabView() tabViewItemAtIndex: nPage] label]);
258 int wxNotebook::GetPageImage(size_t nPage) const
260 // To do this we'd need to keep track of this, which we don't!
264 bool wxNotebook::SetPageImage(size_t nPage, int nImage)
266 const wxBitmap *bmp = nImage!=-1?m_imageList->GetBitmapPtr(nImage):NULL;
269 NSTabViewItem *tvitem = [GetNSTabView() tabViewItemAtIndex: nPage];
272 [(WXCTabViewImageItem*) tvitem setImage: bmp->GetNSImage(true)];
276 int wxNotebook::SetSelection(size_t nPage)
278 const int pageOld = GetSelection();
280 if ( !SendPageChangingEvent(nPage) )
283 int page = ChangeSelection(nPage);
284 if ( page != wxNOT_FOUND )
286 SendPageChangedEvent(pageOld);
292 int wxNotebook::ChangeSelection(size_t nPage)
294 wxAutoNSAutoreleasePool pool;
295 [GetNSTabView() selectTabViewItemAtIndex:nPage];
296 return GetSelection();
299 int wxNotebook::GetSelection() const
301 NSTabViewItem *selectedItem = [GetNSTabView() selectedTabViewItem];
304 return [GetNSTabView() indexOfTabViewItem:selectedItem];
307 void wxNotebook::CocoaDelegate_tabView_didSelectTabViewItem(WX_NSTabViewItem tabViewItem)
309 // FIXME: oldSel probably == newSel
310 wxBookCtrlEvent event(wxEVT_NOTEBOOK_PAGE_CHANGED, GetId(),
311 [GetNSTabView() indexOfTabViewItem:tabViewItem], GetSelection());
312 event.SetEventObject(this);
313 GetEventHandler()->ProcessEvent(event);
316 bool wxNotebook::CocoaDelegate_tabView_shouldSelectTabViewItem(WX_NSTabViewItem tabViewItem)
318 wxBookCtrlEvent event(wxEVT_NOTEBOOK_PAGE_CHANGING, GetId(),
319 [GetNSTabView() indexOfTabViewItem:tabViewItem], GetSelection());
320 event.SetEventObject(this);
321 return !HandleWindowEvent(event) || event.IsAllowed();
324 #endif // wxUSE_NOTEBOOK