]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/notebmac.cpp
Tries to fix wxListBox focus problems.
[wxWidgets.git] / src / mac / notebmac.cpp
... / ...
CommitLineData
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)
37const short kwxMacTabLeftMargin = 20 ;
38const short kwxMacTabTopMargin = 38 ;
39const short kwxMacTabRightMargin = 20 ;
40const short kwxMacTabBottomMargin = 12 ;
41#else
42const short kwxMacTabLeftMargin = 16 ;
43const short kwxMacTabTopMargin = 30 ;
44const short kwxMacTabRightMargin = 16 ;
45const short kwxMacTabBottomMargin = 16 ;
46#endif
47
48// ----------------------------------------------------------------------------
49// event table
50// ----------------------------------------------------------------------------
51
52#if !USE_SHARED_LIBRARIES
53DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED)
54DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING)
55
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{
79#ifdef __DARWIN__
80 m_macHorizontalBorder = 7;
81 m_macVerticalBorder = 8;
82#endif
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
118 m_macControl = ::NewControl( parent->GetMacRootWindow() , &bounds , title , false , 0 , 0 , 1,
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// ----------------------------------------------------------------------------
134
135void wxNotebook::SetPadding(const wxSize& padding)
136{
137 wxFAIL_MSG( wxT("wxNotebook::SetPadding not implemented") );
138}
139
140void wxNotebook::SetTabSize(const wxSize& sz)
141{
142 wxFAIL_MSG( wxT("wxNotebook::SetTabSize not implemented") );
143}
144
145void wxNotebook::SetPageSize(const wxSize& size)
146{
147 wxFAIL_MSG( wxT("wxNotebook::SetPageSize not implemented") );
148}
149
150int 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
161bool 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
172wxString 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
180int wxNotebook::GetPageImage(int nPage) const
181{
182 wxCHECK_MSG( IS_VALID_PAGE(nPage), -1, _T("invalid notebook page") );
183
184 return 0 ;
185}
186
187bool 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
202wxNotebookPage* 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
220bool 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
232bool 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 */
277void 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)
311void 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
338void 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
348void 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
357void 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
378void 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
384bool wxNotebook::DoPhase(int /* nPhase */)
385{
386 return TRUE;
387}
388
389void 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
399void 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
424void 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