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