]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/notebmac.cpp
Various fixes for Textctrl and Popup Menus.
[wxWidgets.git] / src / mac / carbon / notebmac.cpp
CommitLineData
ee6b1d97
SC
1///////////////////////////////////////////////////////////////////////////////
2// Name: notebook.cpp
3// Purpose: implementation of wxNotebook
4// Author: AUTHOR
5// Modified by:
6// Created: ??/??/98
7// RCS-ID: $Id$
8// Copyright: (c) AUTHOR
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19#ifdef __GNUG__
3ef585df 20 #pragma implementation "notebook.h"
ee6b1d97
SC
21#endif
22
d497dca4
GD
23#include "wx/string.h"
24#include "wx/log.h"
25#include "wx/imaglist.h"
26#include "wx/notebook.h"
27#include "wx/mac/uma.h"
ee6b1d97
SC
28// ----------------------------------------------------------------------------
29// macros
30// ----------------------------------------------------------------------------
31
32// check that the page index is valid
33#define IS_VALID_PAGE(nPage) (((nPage) >= 0) && ((nPage) < GetPageCount()))
34
dd47b3d3
SC
35static bool constantsSet = false ;
36
37 short kwxMacTabLeftMargin = 0 ;
38 short kwxMacTabTopMargin = 0 ;
39 short kwxMacTabRightMargin = 0 ;
40 short kwxMacTabBottomMargin = 0 ;
ee6b1d97
SC
41
42// ----------------------------------------------------------------------------
43// event table
44// ----------------------------------------------------------------------------
45
46#if !USE_SHARED_LIBRARIES
5b781a67
SC
47DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED)
48DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING)
49
ee6b1d97
SC
50BEGIN_EVENT_TABLE(wxNotebook, wxControl)
51 EVT_NOTEBOOK_PAGE_CHANGED(-1, wxNotebook::OnSelChange)
52
53 EVT_SIZE(wxNotebook::OnSize)
54 EVT_SET_FOCUS(wxNotebook::OnSetFocus)
55 EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
56END_EVENT_TABLE()
57
58IMPLEMENT_DYNAMIC_CLASS(wxNotebook, wxControl)
59IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxCommandEvent)
60#endif
61
62// ============================================================================
63// implementation
64// ============================================================================
65
66// ----------------------------------------------------------------------------
67// wxNotebook construction
68// ----------------------------------------------------------------------------
69
70// common part of all ctors
71void wxNotebook::Init()
72{
dd47b3d3
SC
73 if ( !constantsSet )
74 {
75 if ( UMAHasAquaLayout() )
76 {
77 // I got these values for Mac OS X from the Appearance mgr docs. (Mark Newsam)
78 kwxMacTabLeftMargin = 20 ;
79 kwxMacTabTopMargin = 38 ;
80 kwxMacTabRightMargin = 20 ;
81 kwxMacTabBottomMargin = 12 ;
82 }
83 else
84 {
85 kwxMacTabLeftMargin = 16 ;
86 kwxMacTabTopMargin = 30 ;
87 kwxMacTabRightMargin = 16 ;
88 kwxMacTabBottomMargin = 16 ;
89 }
90 constantsSet = true ;
91 }
92 if ( UMAHasAquaLayout() )
93 {
94 m_macHorizontalBorder = 7;
95 m_macVerticalBorder = 8;
96 }
97
ee6b1d97
SC
98 m_nSelection = -1;
99}
100
101// default for dynamic class
102wxNotebook::wxNotebook()
103{
104 Init();
105}
106
107// the same arguments as for wxControl
108wxNotebook::wxNotebook(wxWindow *parent,
109 wxWindowID id,
110 const wxPoint& pos,
111 const wxSize& size,
112 long style,
113 const wxString& name)
114{
115 Init();
116
117 Create(parent, id, pos, size, style, name);
118}
119
120// Create() function
121bool wxNotebook::Create(wxWindow *parent,
122 wxWindowID id,
123 const wxPoint& pos,
124 const wxSize& size,
125 long style,
126 const wxString& name)
127{
128 Rect bounds ;
129 Str255 title ;
130
131 MacPreControlCreate( parent , id , "" , pos , size ,style, wxDefaultValidator , name , &bounds , title ) ;
132
76a5e5d2 133 m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 , 0 , 1,
ee6b1d97
SC
134 kControlTabSmallProc , (long) this ) ;
135
136 MacPostControlCreate() ;
137 return TRUE ;
138}
139
140// dtor
141wxNotebook::~wxNotebook()
142{
143 m_macControl = NULL ;
144}
145
60ec3e58
RR
146wxSize wxNotebook::CalcSizeFromPage(const wxSize& sizePage)
147{
148 wxSize sizeTotal = sizePage;
149
150 int major,minor;
151 wxGetOsVersion( &major, &minor );
152
153 // Mac has large notebook borders. Aqua even more so.
154
155 if ( HasFlag(wxNB_LEFT) || HasFlag(wxNB_RIGHT) )
156 {
157 sizeTotal.x += 90;
158
159 if (major >= 10)
160 sizeTotal.y += 28;
161 else
162 sizeTotal.y += 20;
163 }
164 else
165 {
166 if (major >= 10)
167 {
168 sizeTotal.x += 34;
169 sizeTotal.y += 46;
170 }
171 else
172 {
173 sizeTotal.x += 22;
174 sizeTotal.y += 44;
175 }
176 }
177
178 return sizeTotal;
179}
180
ee6b1d97
SC
181// ----------------------------------------------------------------------------
182// wxNotebook accessors
183// ----------------------------------------------------------------------------
90b959ae
SC
184
185void wxNotebook::SetPadding(const wxSize& padding)
186{
fc0daf84 187 wxFAIL_MSG( wxT("wxNotebook::SetPadding not implemented") );
90b959ae
SC
188}
189
190void wxNotebook::SetTabSize(const wxSize& sz)
ee6b1d97 191{
fc0daf84 192 wxFAIL_MSG( wxT("wxNotebook::SetTabSize not implemented") );
ee6b1d97
SC
193}
194
90b959ae 195void wxNotebook::SetPageSize(const wxSize& size)
ee6b1d97 196{
fc0daf84 197 wxFAIL_MSG( wxT("wxNotebook::SetPageSize not implemented") );
ee6b1d97
SC
198}
199
200int wxNotebook::SetSelection(int nPage)
201{
9453cf2b
SC
202 if( !IS_VALID_PAGE(nPage) )
203 return m_nSelection ;
ee6b1d97
SC
204
205 ChangePage(m_nSelection, nPage);
76a5e5d2 206 SetControlValue( (ControlHandle) m_macControl , m_nSelection + 1 ) ;
c854c7d9 207
ee6b1d97
SC
208 return m_nSelection;
209}
210
ee6b1d97
SC
211bool wxNotebook::SetPageText(int nPage, const wxString& strText)
212{
213 wxASSERT( IS_VALID_PAGE(nPage) );
214
90b959ae 215 wxNotebookPage *page = m_pages[nPage];
c854c7d9
GD
216 page->SetLabel(strText);
217 MacSetupTabs();
218
219 return true;
ee6b1d97
SC
220}
221
222wxString wxNotebook::GetPageText(int nPage) const
223{
224 wxASSERT( IS_VALID_PAGE(nPage) );
225
90b959ae 226 wxNotebookPage *page = m_pages[nPage];
c854c7d9 227 return page->GetLabel();
ee6b1d97
SC
228}
229
230int wxNotebook::GetPageImage(int nPage) const
231{
fc0daf84 232 wxCHECK_MSG( IS_VALID_PAGE(nPage), -1, _T("invalid notebook page") );
ee6b1d97 233
fc0daf84 234 return 0 ;
ee6b1d97
SC
235}
236
237bool wxNotebook::SetPageImage(int nPage, int nImage)
238{
fc0daf84
SC
239 wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, _T("invalid notebook page") );
240
241 wxCHECK_MSG( m_imageList && nImage < m_imageList->GetImageCount(), FALSE,
242 _T("invalid image index in SetPageImage()") );
ee6b1d97 243
ee6b1d97
SC
244 return FALSE;
245}
246
ee6b1d97
SC
247// ----------------------------------------------------------------------------
248// wxNotebook operations
249// ----------------------------------------------------------------------------
250
90b959ae
SC
251// remove one page from the notebook, without deleting the window
252wxNotebookPage* wxNotebook::DoRemovePage(int nPage)
ee6b1d97 253{
90b959ae
SC
254 wxCHECK( IS_VALID_PAGE(nPage), NULL );
255 wxNotebookPage* page = m_pages[nPage] ;
3ef585df 256 m_pages.RemoveAt(nPage);
ee6b1d97 257
c854c7d9
GD
258 MacSetupTabs();
259
260 if(m_nSelection >= GetPageCount()) {
261 m_nSelection = GetPageCount() - 1;
262 }
263 if(m_nSelection >= 0) {
90b959ae 264 m_pages[m_nSelection]->Show(true);
c854c7d9 265 }
90b959ae 266 return page;
ee6b1d97
SC
267}
268
269// remove all pages
270bool wxNotebook::DeleteAllPages()
271{
272 // TODO: delete native widget pages
273
90b959ae 274 WX_CLEAR_ARRAY(m_pages) ;
c854c7d9
GD
275 MacSetupTabs();
276
ee6b1d97
SC
277 return TRUE;
278}
279
ee6b1d97
SC
280
281// same as AddPage() but does it at given position
282bool wxNotebook::InsertPage(int nPage,
283 wxNotebookPage *pPage,
284 const wxString& strText,
285 bool bSelect,
286 int imageId)
287{
288 wxASSERT( pPage != NULL );
289 wxCHECK( IS_VALID_PAGE(nPage) || nPage == GetPageCount(), FALSE );
290
c854c7d9 291 pPage->SetLabel(strText);
ee6b1d97
SC
292
293 // save the pointer to the page
90b959ae 294 m_pages.Insert(pPage, nPage);
ee6b1d97 295
c854c7d9
GD
296 MacSetupTabs();
297
298 if ( bSelect ) {
ee6b1d97 299 m_nSelection = nPage;
c854c7d9
GD
300 }
301 else if ( m_nSelection == -1 ) {
ee6b1d97 302 m_nSelection = 0;
c854c7d9
GD
303 }
304 else if (m_nSelection >= nPage) {
305 m_nSelection++;
306 }
307 // don't show pages by default (we'll need to adjust their size first)
308 pPage->Show( false ) ;
ee6b1d97 309
c854c7d9
GD
310 int h, w;
311 GetSize(&w, &h);
312 pPage->SetSize(kwxMacTabLeftMargin, kwxMacTabTopMargin,
313 w - kwxMacTabLeftMargin - kwxMacTabRightMargin,
314 h - kwxMacTabTopMargin - kwxMacTabBottomMargin );
315 if ( pPage->GetAutoLayout() ) {
316 pPage->Layout();
317 }
ee6b1d97 318
c854c7d9
GD
319 return true;
320}
321
322/* Added by Mark Newsam
323 * When a page is added or deleted to the notebook this function updates
324 * information held in the m_macControl so that it matches the order
325 * the user would expect.
326 */
327void wxNotebook::MacSetupTabs()
328{
76a5e5d2 329 SetControlMaximum( (ControlHandle) m_macControl , GetPageCount() ) ;
c854c7d9
GD
330
331 wxNotebookPage *page;
332 ControlTabInfoRec info;
333 Boolean enabled = true;
334 for(int ii = 0; ii < GetPageCount(); ii++)
335 {
90b959ae 336 page = m_pages[ii];
c854c7d9
GD
337 info.version = 0;
338 info.iconSuiteID = 0;
339#if TARGET_CARBON
340 c2pstrcpy( (StringPtr) info.name , page->GetLabel() ) ;
341#else
342 strcpy( (char *) info.name , page->GetLabel() ) ;
343 c2pstr( (char *) info.name ) ;
344#endif
76a5e5d2 345 SetControlData( (ControlHandle) m_macControl, ii+1, kControlTabInfoTag,
c854c7d9 346 sizeof( ControlTabInfoRec) , (char*) &info ) ;
76a5e5d2 347 SetControlData( (ControlHandle) m_macControl, ii+1, kControlTabEnabledFlagTag,
c854c7d9
GD
348 sizeof( Boolean ), (Ptr)&enabled );
349 }
350 Rect bounds;
76a5e5d2
SC
351 GetControlBounds((ControlHandle)m_macControl, &bounds);
352 InvalWindowRect((WindowRef)MacGetRootWindow(), &bounds);
ee6b1d97
SC
353}
354
355// ----------------------------------------------------------------------------
356// wxNotebook callbacks
357// ----------------------------------------------------------------------------
358
359// @@@ OnSize() is used for setting the font when it's called for the first
360// time because doing it in ::Create() doesn't work (for unknown reasons)
361void wxNotebook::OnSize(wxSizeEvent& event)
362{
ee6b1d97
SC
363 // emulate page change (it's esp. important to do it first time because
364 // otherwise our page would stay invisible)
365 int nSel = m_nSelection;
366 m_nSelection = -1;
367 SetSelection(nSel);
368
369 // fit the notebook page to the tab control's display area
370 int w, h;
371 GetSize(&w, &h);
372
90b959ae 373 unsigned int nCount = m_pages.Count();
ee6b1d97 374 for ( unsigned int nPage = 0; nPage < nCount; nPage++ ) {
90b959ae 375 wxNotebookPage *pPage = m_pages[nPage];
c854c7d9
GD
376 pPage->SetSize(kwxMacTabLeftMargin, kwxMacTabTopMargin,
377 w - kwxMacTabLeftMargin - kwxMacTabRightMargin,
378 h - kwxMacTabTopMargin - kwxMacTabBottomMargin );
379 if ( pPage->GetAutoLayout() ) {
ee6b1d97 380 pPage->Layout();
c854c7d9 381 }
ee6b1d97
SC
382 }
383
384 // Processing continues to next OnSize
385 event.Skip();
386}
387
388void wxNotebook::OnSelChange(wxNotebookEvent& event)
389{
390 // is it our tab control?
391 if ( event.GetEventObject() == this )
392 ChangePage(event.GetOldSelection(), event.GetSelection());
393
394 // we want to give others a chance to process this message as well
395 event.Skip();
396}
397
398void wxNotebook::OnSetFocus(wxFocusEvent& event)
399{
400 // set focus to the currently selected page if any
401 if ( m_nSelection != -1 )
90b959ae 402 m_pages[m_nSelection]->SetFocus();
ee6b1d97
SC
403
404 event.Skip();
405}
406
407void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
408{
409 if ( event.IsWindowChange() ) {
410 // change pages
411 AdvanceSelection(event.GetDirection());
412 }
413 else {
414 // pass to the parent
415 if ( GetParent() ) {
416 event.SetCurrentFocus(this);
417 GetParent()->ProcessEvent(event);
418 }
419 }
420}
421
422// ----------------------------------------------------------------------------
423// wxNotebook base class virtuals
424// ----------------------------------------------------------------------------
425
426// override these 2 functions to do nothing: everything is done in OnSize
427
428void wxNotebook::SetConstraintSizes(bool /* recurse */)
429{
430 // don't set the sizes of the pages - their correct size is not yet known
431 wxControl::SetConstraintSizes(FALSE);
432}
433
434bool wxNotebook::DoPhase(int /* nPhase */)
435{
436 return TRUE;
437}
438
439void wxNotebook::Command(wxCommandEvent& event)
440{
441 wxFAIL_MSG("wxNotebook::Command not implemented");
442}
443
444// ----------------------------------------------------------------------------
445// wxNotebook helper functions
446// ----------------------------------------------------------------------------
447
448// hide the currently active panel and show the new one
449void wxNotebook::ChangePage(int nOldSel, int nSel)
450{
c854c7d9
GD
451 // it's not an error (the message may be generated by the tab control itself)
452 // and it may happen - just do nothing
453 if ( nSel == nOldSel )
454 {
90b959ae 455 wxNotebookPage *pPage = m_pages[nSel];
c854c7d9
GD
456 pPage->Show(FALSE);
457 pPage->Show(TRUE);
458 pPage->SetFocus();
459 return;
460 }
ee6b1d97 461
c854c7d9 462 // Hide previous page
ee6b1d97 463 if ( nOldSel != -1 ) {
90b959ae 464 m_pages[nOldSel]->Show(FALSE);
ee6b1d97
SC
465 }
466
90b959ae 467 wxNotebookPage *pPage = m_pages[nSel];
ee6b1d97
SC
468 pPage->Show(TRUE);
469 pPage->SetFocus();
470
471 m_nSelection = nSel;
472}
473
76a5e5d2 474void wxNotebook::MacHandleControlClick( WXWidget control , wxInt16 controlpart )
ee6b1d97 475{
76a5e5d2 476 wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, m_windowId , ::GetControlValue((ControlHandle)m_macControl) - 1, m_nSelection);
ee6b1d97
SC
477 event.SetEventObject(this);
478
479 ProcessEvent(event);
480}
481