]> git.saurik.com Git - wxWidgets.git/blob - src/os2/notebook.cpp
Several updates for fixing the subclassing problems and accelerator processing
[wxWidgets.git] / src / os2 / notebook.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: notebook.cpp
3 // Purpose: implementation of wxNotebook
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/12/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 // wxWindows
16 #ifndef WX_PRECOMP
17 #include <wx/string.h>
18 #endif // WX_PRECOMP
19
20 #include <wx/log.h>
21 #include <wx/imaglist.h>
22 #include <wx/event.h>
23 #include <wx/control.h>
24 #include <wx/notebook.h>
25
26 #include <wx/os2/private.h>
27
28
29 // ----------------------------------------------------------------------------
30 // macros
31 // ----------------------------------------------------------------------------
32 // check that the page index is valid
33 #define IS_VALID_PAGE(nPage) (((nPage) >= 0) && ((nPage) < GetPageCount()))
34
35 // hide the ugly cast
36 #define m_hwnd (HWND)GetHWND()
37
38 // ----------------------------------------------------------------------------
39 // constants
40 // ----------------------------------------------------------------------------
41
42 // This is a work-around for missing defines in gcc-2.95 headers
43 #ifndef TCS_RIGHT
44 #define TCS_RIGHT 0x0002
45 #endif
46
47 #ifndef TCS_VERTICAL
48 #define TCS_VERTICAL 0x0080
49 #endif
50
51 #ifndef TCS_BOTTOM
52 #define TCS_BOTTOM TCS_RIGHT
53 #endif
54
55 // ----------------------------------------------------------------------------
56 // event table
57 // ----------------------------------------------------------------------------
58
59 BEGIN_EVENT_TABLE(wxNotebook, wxControl)
60 EVT_NOTEBOOK_PAGE_CHANGED(-1, wxNotebook::OnSelChange)
61 EVT_SIZE(wxNotebook::OnSize)
62 EVT_SET_FOCUS(wxNotebook::OnSetFocus)
63 EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
64 END_EVENT_TABLE()
65
66 IMPLEMENT_DYNAMIC_CLASS(wxNotebook, wxControl)
67 IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxNotifyEvent)
68
69 // ============================================================================
70 // implementation
71 // ============================================================================
72
73 // ----------------------------------------------------------------------------
74 // wxNotebook construction
75 // ----------------------------------------------------------------------------
76
77 // common part of all ctors
78 void wxNotebook::Init()
79 {
80 m_pImageList = NULL;
81 m_nSelection = -1;
82 }
83
84 // default for dynamic class
85 wxNotebook::wxNotebook()
86 {
87 Init();
88 }
89
90 // the same arguments as for wxControl
91 wxNotebook::wxNotebook(wxWindow *parent,
92 wxWindowID id,
93 const wxPoint& pos,
94 const wxSize& size,
95 long style,
96 const wxString& name)
97 {
98 Init();
99
100 Create(parent, id, pos, size, style, name);
101 }
102
103 // Create() function
104 bool wxNotebook::Create(wxWindow *parent,
105 wxWindowID id,
106 const wxPoint& pos,
107 const wxSize& size,
108 long style,
109 const wxString& name)
110 {
111 // base init
112 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
113 return FALSE;
114
115 // colors and font
116 // TODO: m_backgroundColour = wxColour(GetSysColor(COLOR_BTNFACE));
117 m_foregroundColour = *wxBLACK ;
118
119 // TODO:
120 /*
121 // style
122 m_windowStyle = style | wxTAB_TRAVERSAL;
123
124 long tabStyle = WS_CHILD | WS_VISIBLE | WS_TABSTOP | TCS_TABS;
125
126 if (m_windowStyle & wxCLIP_CHILDREN)
127 tabStyle |= WS_CLIPCHILDREN;
128 if ( m_windowStyle & wxTC_MULTILINE )
129 tabStyle |= TCS_MULTILINE;
130 if ( m_windowStyle & wxBORDER )
131 tabStyle &= WS_BORDER;
132 if (m_windowStyle & wxNB_FIXEDWIDTH)
133 tabStyle |= TCS_FIXEDWIDTH ;
134 if (m_windowStyle & wxNB_BOTTOM)
135 tabStyle |= TCS_RIGHT;
136 if (m_windowStyle & wxNB_LEFT)
137 tabStyle |= TCS_VERTICAL;
138 if (m_windowStyle & wxNB_RIGHT)
139 tabStyle |= TCS_VERTICAL|TCS_RIGHT;
140
141
142 if ( !MSWCreate(GetId(), GetParent(), WC_TABCONTROL,
143 this, NULL, pos.x, pos.y, size.x, size.y,
144 tabStyle, NULL, 0) )
145 {
146 return FALSE;
147 }
148
149 // Not all compilers recognise SetWindowFont
150 ::SendMessage(GetHwnd(), WM_SETFONT,
151 (WPARAM)::GetStockObject(DEFAULT_GUI_FONT), TRUE);
152
153
154 if ( parent != NULL )
155 parent->AddChild(this);
156 */
157 SubclassWin(m_hWnd);
158
159 return FALSE;
160 }
161
162 // dtor
163 wxNotebook::~wxNotebook()
164 {
165 }
166
167 // ----------------------------------------------------------------------------
168 // wxNotebook accessors
169 // ----------------------------------------------------------------------------
170 int wxNotebook::GetPageCount() const
171 {
172 return m_aPages.Count();
173 }
174
175 int wxNotebook::GetRowCount() const
176 {
177 // TODO
178 return 0;
179 }
180
181 int wxNotebook::SetSelection(int nPage)
182 {
183 wxCHECK_MSG( IS_VALID_PAGE(nPage), -1, wxT("notebook page out of range") );
184
185 ChangePage(m_nSelection, nPage);
186
187 // TODO
188 return 0;
189 }
190
191 void wxNotebook::AdvanceSelection(bool bForward)
192 {
193 int nSel = GetSelection();
194 int nMax = GetPageCount() - 1;
195 if ( bForward )
196 SetSelection(nSel == nMax ? 0 : nSel + 1);
197 else
198 SetSelection(nSel == 0 ? nMax : nSel - 1);
199 }
200
201 bool wxNotebook::SetPageText(int nPage, const wxString& strText)
202 {
203 wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, wxT("notebook page out of range") );
204
205 // TODO
206 return FALSE;
207 }
208
209 wxString wxNotebook::GetPageText(int nPage) const
210 {
211 wxCHECK_MSG( IS_VALID_PAGE(nPage), wxT(""), wxT("notebook page out of range") );
212
213 // TODO
214 return wxString("");
215 }
216
217 int wxNotebook::GetPageImage(int nPage) const
218 {
219 wxCHECK_MSG( IS_VALID_PAGE(nPage), -1, wxT("notebook page out of range") );
220
221 // TODO
222 return 0;
223 }
224
225 bool wxNotebook::SetPageImage(int nPage, int nImage)
226 {
227 wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, wxT("notebook page out of range") );
228
229 // TODO
230 return FALSE;
231 }
232
233 void wxNotebook::SetImageList(wxImageList* imageList)
234 {
235 m_pImageList = imageList;
236 // TODO
237 }
238
239 void wxNotebook::SetTabSize(const wxSize& sz)
240 {
241 // TODO
242 }
243
244 // ----------------------------------------------------------------------------
245 // wxNotebook operations
246 // ----------------------------------------------------------------------------
247
248 // remove one page from the notebook
249 bool wxNotebook::DeletePage(int nPage)
250 {
251 wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, wxT("notebook page out of range") );
252
253 // TODO: delete native widget page
254
255 delete m_aPages[nPage];
256 m_aPages.Remove(nPage);
257
258 return TRUE;
259 }
260
261 // remove one page from the notebook, without deleting the window
262 bool wxNotebook::RemovePage(int nPage)
263 {
264 wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, wxT("notebook page out of range") );
265
266 m_aPages.Remove(nPage);
267
268 return TRUE;
269 }
270
271 // remove all pages
272 bool wxNotebook::DeleteAllPages()
273 {
274 // TODO: delete native widget pages
275
276 int nPageCount = GetPageCount();
277 int nPage;
278 for ( nPage = 0; nPage < nPageCount; nPage++ )
279 delete m_aPages[nPage];
280
281 m_aPages.Clear();
282
283 return TRUE;
284 }
285
286 // add a page to the notebook
287 bool wxNotebook::AddPage(wxNotebookPage *pPage,
288 const wxString& strText,
289 bool bSelect,
290 int imageId)
291 {
292 return InsertPage(GetPageCount(), pPage, strText, bSelect, imageId);
293 }
294
295 // same as AddPage() but does it at given position
296 bool wxNotebook::InsertPage(int nPage,
297 wxNotebookPage *pPage,
298 const wxString& strText,
299 bool bSelect,
300 int imageId)
301 {
302 wxASSERT( pPage != NULL );
303 wxCHECK( IS_VALID_PAGE(nPage) || nPage == GetPageCount(), FALSE );
304
305 // TODO: insert native widget page
306
307 // save the pointer to the page
308 m_aPages.Insert(pPage, nPage);
309
310 // some page must be selected: either this one or the first one if there is
311 // still no selection
312 if ( bSelect )
313 m_nSelection = nPage;
314 else if ( m_nSelection == -1 )
315 m_nSelection = 0;
316
317 return TRUE;
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 static bool s_bFirstTime = TRUE;
329 if ( s_bFirstTime ) {
330 // TODO: any first-time-size processing.
331 s_bFirstTime = FALSE;
332 }
333
334 // TODO: all this may or may not be necessary for your platform
335
336 // emulate page change (it's esp. important to do it first time because
337 // otherwise our page would stay invisible)
338 int nSel = m_nSelection;
339 m_nSelection = -1;
340 SetSelection(nSel);
341
342 // fit the notebook page to the tab control's display area
343 int w, h;
344 GetSize(&w, &h);
345
346 unsigned int nCount = m_aPages.Count();
347 for ( unsigned int nPage = 0; nPage < nCount; nPage++ ) {
348 wxNotebookPage *pPage = m_aPages[nPage];
349 pPage->SetSize(0, 0, w, h);
350 if ( pPage->GetAutoLayout() )
351 pPage->Layout();
352 }
353
354 // Processing continues to next OnSize
355 event.Skip();
356 }
357
358 void wxNotebook::OnSelChange(wxNotebookEvent& event)
359 {
360 // is it our tab control?
361 if ( event.GetEventObject() == this )
362 {
363 int sel = event.GetOldSelection();
364 if ( sel != -1 )
365 m_aPages[sel]->Show(FALSE);
366
367 sel = event.GetSelection();
368 if ( sel != -1 )
369 {
370 wxNotebookPage *pPage = m_aPages[sel];
371 pPage->Show(TRUE);
372 pPage->SetFocus();
373 }
374
375 m_nSelection = sel;
376 }
377 // we want to give others a chance to process this message as well
378 event.Skip();
379 }
380
381 void wxNotebook::OnSetFocus(wxFocusEvent& event)
382 {
383 // set focus to the currently selected page if any
384 if ( m_nSelection != -1 )
385 m_aPages[m_nSelection]->SetFocus();
386
387 event.Skip();
388 }
389
390 void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
391 {
392 if ( event.IsWindowChange() ) {
393 // change pages
394 AdvanceSelection(event.GetDirection());
395 }
396 else {
397 // pass to the parent
398 if ( GetParent() ) {
399 event.SetCurrentFocus(this);
400 GetParent()->ProcessEvent(event);
401 }
402 }
403 }
404
405 // ----------------------------------------------------------------------------
406 // wxNotebook base class virtuals
407 // ----------------------------------------------------------------------------
408
409 // override these 2 functions to do nothing: everything is done in OnSize
410
411 void wxNotebook::SetConstraintSizes(bool /* recurse */)
412 {
413 // don't set the sizes of the pages - their correct size is not yet known
414 wxControl::SetConstraintSizes(FALSE);
415 }
416
417 bool wxNotebook::DoPhase(int /* nPhase */)
418 {
419 return TRUE;
420 }
421
422 bool wxNotebook::OS2OnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM* result)
423 {
424 wxNotebookEvent event(wxEVT_NULL, m_windowId);
425 //TODO:
426 /*
427 NMHDR* hdr = (NMHDR *)lParam;
428 switch ( hdr->code ) {
429 case TCN_SELCHANGE:
430 event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED);
431 break;
432
433 case TCN_SELCHANGING:
434 event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING);
435 break;
436
437 default:
438 return wxControl::MSWOnNotify(idCtrl, lParam, result);
439 }
440 */
441 // TODO: event.SetSelection(TabCtrl_GetCurSel(m_hwnd));
442 event.SetOldSelection(m_nSelection);
443 event.SetEventObject(this);
444 event.SetInt(idCtrl);
445
446 bool processed = GetEventHandler()->ProcessEvent(event);
447 // TODO: *result = !event.IsAllowed();
448 return processed;
449 }
450
451 // ----------------------------------------------------------------------------
452 // wxNotebook helper functions
453 // ----------------------------------------------------------------------------
454
455 // hide the currently active panel and show the new one
456 void wxNotebook::ChangePage(int nOldSel, int nSel)
457 {
458 // MT-FIXME should use a real semaphore
459 static bool s_bInsideChangePage = FALSE;
460
461 // when we call ProcessEvent(), our own OnSelChange() is called which calls
462 // this function - break the infinite loop
463 if ( s_bInsideChangePage )
464 return;
465
466 // it's not an error (the message may be generated by the tab control itself)
467 // and it may happen - just do nothing
468 if ( nSel == nOldSel )
469 return;
470
471 s_bInsideChangePage = TRUE;
472
473 wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, m_windowId);
474 event.SetSelection(nSel);
475 event.SetOldSelection(nOldSel);
476 event.SetEventObject(this);
477 if ( ProcessEvent(event) && !event.IsAllowed() )
478 {
479 // program doesn't allow the page change
480 s_bInsideChangePage = FALSE;
481 return;
482 }
483
484 event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED);
485 ProcessEvent(event);
486
487 s_bInsideChangePage = FALSE;
488 }
489