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"
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
52 @implementation WXCTabViewImageItem : NSTabViewItem
55 return [self initWithIdentifier:nil];
58 - (id)initWithIdentifier: (id)identifier;
61 return [super initWithIdentifier:identifier];
70 - (NSSize)sizeOfLabel:(BOOL)shouldTruncateLabel
72 NSSize labelSize = [super sizeOfLabel:shouldTruncateLabel];
75 NSSize imageSize = [m_image size];
77 if(imageSize.height > labelSize.height)
79 imageSize.width *= labelSize.height/imageSize.height;
80 imageSize.height *= labelSize.height/imageSize.height;
81 [m_image setScalesWhenResized:YES];
82 [m_image setSize: imageSize];
84 labelSize.width += imageSize.width;
88 - (void)drawLabel:(BOOL)shouldTruncateLabel inRect:(NSRect)tabRect
92 NSSize imageSize = [m_image size];
93 [m_image compositeToPoint:NSMakePoint(tabRect.origin.x,
94 tabRect.origin.y+imageSize.height)
95 operation:NSCompositeSourceOver];
96 tabRect.size.width -= imageSize.width;
97 tabRect.origin.x += imageSize.width;
99 [super drawLabel:shouldTruncateLabel inRect:tabRect];
107 - (void)setImage:(NSImage*)image
114 [[NSPasteboard generalPasteboard]
115 declareTypes:[NSArray arrayWithObject:NSTIFFPboardType]
117 [[NSPasteboard generalPasteboard]
118 setData:[m_image TIFFRepresentation]
119 forType:NSTIFFPboardType];
122 @end // implementation WXCTabViewImageItem : NSTabViewItem
124 // ========================================================================
126 // ========================================================================
127 DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED)
128 DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING)
129 IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxNotifyEvent)
131 // ========================================================================
133 // ========================================================================
134 IMPLEMENT_DYNAMIC_CLASS(wxNotebook, wxControl)
135 BEGIN_EVENT_TABLE(wxNotebook, wxNotebookBase)
137 WX_IMPLEMENT_COCOA_OWNER(wxNotebook,NSTabView,NSView,NSView)
139 bool wxNotebook::Create(wxWindow *parent, wxWindowID winid,
143 const wxString& name)
145 wxAutoNSAutoreleasePool pool;
146 if(!CreateControl(parent,winid,pos,size,style,wxDefaultValidator,name))
148 m_cocoaNSView = NULL;
149 SetNSTabView([[NSTabView alloc] initWithFrame:MakeDefaultNSRect(size)]);
153 NSTabViewType tabViewType;
155 tabViewType = NSTopTabsBezelBorder;
156 else if(style & wxNB_LEFT)
157 tabViewType = NSLeftTabsBezelBorder;
158 else if(style & wxNB_RIGHT)
159 tabViewType = NSRightTabsBezelBorder;
160 else if(style & wxNB_BOTTOM)
161 tabViewType = NSBottomTabsBezelBorder;
164 [GetNSTabView() setTabViewType:tabViewType];
168 m_parent->CocoaAddChild(this);
169 SetInitialFrameRect(pos,size);
174 wxNotebook::~wxNotebook()
178 void wxNotebook::SetPadding(const wxSize& padding)
182 void wxNotebook::SetTabSize(const wxSize& sz)
186 void wxNotebook::SetPageSize(const wxSize& size)
191 wxNotebookPage *wxNotebook::DoRemovePage(size_t nPage)
193 wxNotebookPage *page = wxNotebookBase::DoRemovePage(nPage);
196 NSTabViewItem *tvitem = [GetNSTabView() tabViewItemAtIndex: nPage];
199 [GetNSTabView() removeTabViewItem:tvitem];
200 // Remove the child window as a notebook page
201 wxASSERT(static_cast<NSView*>([tvitem view]) == page->GetNSViewForSuperview());
202 [tvitem setView:nil];
204 // Make it back into a normal child window
205 [m_cocoaNSView addSubview: page->GetNSViewForSuperview()];
210 bool wxNotebook::DeletePage(size_t nPage)
212 return wxNotebookBase::DeletePage(nPage);
215 bool wxNotebook::InsertPage( size_t pos,
216 wxNotebookPage *page, const wxString& title,
217 bool bSelect, int imageId)
219 wxAutoNSAutoreleasePool pool;
220 m_pages.Insert(page,pos);
221 NSTabViewItem *tvitem = [[WXCTabViewImageItem alloc] initWithIdentifier:nil];
222 [tvitem setLabel: wxNSStringWithWxString(title)];
223 const wxBitmap *bmp = (imageId!=-1)?m_imageList->GetBitmapPtr(imageId):NULL;
225 [(WXCTabViewImageItem*) tvitem setImage: bmp->GetNSImage(true)];
227 NSView *pageNSView = page->GetNSViewForSuperview();
228 // Remove it as a normal child
229 wxASSERT(m_cocoaNSView == [pageNSView superview]);
230 [pageNSView removeFromSuperview];
231 // And make it a notebook page
232 [tvitem setView: pageNSView];
234 [GetNSTabView() insertTabViewItem:tvitem atIndex:pos];
240 bool wxNotebook::DeleteAllPages()
242 while(!m_pages.IsEmpty())
248 bool wxNotebook::SetPageText(size_t nPage, const wxString& title)
250 NSTabViewItem *tvitem = [GetNSTabView() tabViewItemAtIndex: nPage];
253 [tvitem setLabel: wxNSStringWithWxString(title)];
257 wxString wxNotebook::GetPageText(size_t nPage) const
259 return wxStringWithNSString([[GetNSTabView() tabViewItemAtIndex: nPage] label]);
263 int wxNotebook::GetPageImage(size_t nPage) const
265 // To do this we'd need to keep track of this, which we don't!
269 bool wxNotebook::SetPageImage(size_t nPage, int nImage)
271 const wxBitmap *bmp = nImage!=-1?m_imageList->GetBitmapPtr(nImage):NULL;
274 NSTabViewItem *tvitem = [GetNSTabView() tabViewItemAtIndex: nPage];
277 [(WXCTabViewImageItem*) tvitem setImage: bmp->GetNSImage(true)];
281 int wxNotebook::SetSelection(size_t nPage)
283 const int pageOld = GetSelection();
285 if ( !SendPageChangingEvent(nPage) )
288 int page = ChangeSelection(nPage);
289 if ( page != wxNOT_FOUND )
291 SendPageChangedEvent(pageOld);
297 int wxNotebook::ChangeSelection(size_t nPage)
299 wxAutoNSAutoreleasePool pool;
300 [GetNSTabView() selectTabViewItemAtIndex:nPage];
301 return GetSelection();
304 int wxNotebook::GetSelection() const
306 NSTabViewItem *selectedItem = [GetNSTabView() selectedTabViewItem];
309 return [GetNSTabView() indexOfTabViewItem:selectedItem];
312 void wxNotebook::CocoaDelegate_tabView_didSelectTabViewItem(WX_NSTabViewItem tabViewItem)
314 // FIXME: oldSel probably == newSel
315 wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, GetId(),
316 [GetNSTabView() indexOfTabViewItem:tabViewItem], GetSelection());
317 event.SetEventObject(this);
320 bool wxNotebook::CocoaDelegate_tabView_shouldSelectTabViewItem(WX_NSTabViewItem tabViewItem)
322 wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, GetId(),
323 [GetNSTabView() indexOfTabViewItem:tabViewItem], GetSelection());
324 event.SetEventObject(this);
325 return !GetEventHandler()->ProcessEvent(event) || event.IsAllowed();
328 #endif // wxUSE_NOTEBOOK