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