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