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