]> git.saurik.com Git - wxWidgets.git/blame - src/os2/notebook.cpp
Merged some STC fixes over to the main branch
[wxWidgets.git] / src / os2 / notebook.cpp
CommitLineData
0e320a79
DW
1///////////////////////////////////////////////////////////////////////////////
2// Name: notebook.cpp
3// Purpose: implementation of wxNotebook
cdf1e714 4// Author: David Webster
fb46a9a6 5// Modified by:
cdf1e714 6// Created: 10/12/99
0e320a79 7// RCS-ID: $Id$
cdf1e714 8// Copyright: (c) David Webster
0e320a79
DW
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
cdf1e714
DW
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
0e320a79 14
cdf1e714
DW
15// wxWindows
16#ifndef WX_PRECOMP
17 #include <wx/string.h>
18#endif // WX_PRECOMP
0e320a79 19
0e320a79
DW
20#include <wx/log.h>
21#include <wx/imaglist.h>
cdf1e714
DW
22#include <wx/event.h>
23#include <wx/control.h>
0e320a79
DW
24#include <wx/notebook.h>
25
cdf1e714
DW
26#include <wx/os2/private.h>
27
28
0e320a79
DW
29// ----------------------------------------------------------------------------
30// macros
31// ----------------------------------------------------------------------------
0e320a79
DW
32// check that the page index is valid
33#define IS_VALID_PAGE(nPage) (((nPage) >= 0) && ((nPage) < GetPageCount()))
34
cdf1e714
DW
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
0e320a79
DW
55// ----------------------------------------------------------------------------
56// event table
57// ----------------------------------------------------------------------------
58
cdf1e714 59 BEGIN_EVENT_TABLE(wxNotebook, wxControl)
0e320a79 60 EVT_NOTEBOOK_PAGE_CHANGED(-1, wxNotebook::OnSelChange)
0e320a79
DW
61 EVT_SIZE(wxNotebook::OnSize)
62 EVT_SET_FOCUS(wxNotebook::OnSetFocus)
63 EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
cdf1e714 64 END_EVENT_TABLE()
0e320a79 65
cdf1e714
DW
66 IMPLEMENT_DYNAMIC_CLASS(wxNotebook, wxControl)
67 IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxNotifyEvent)
0e320a79
DW
68
69// ============================================================================
70// implementation
71// ============================================================================
72
73// ----------------------------------------------------------------------------
74// wxNotebook construction
75// ----------------------------------------------------------------------------
76
77// common part of all ctors
78void wxNotebook::Init()
79{
80 m_pImageList = NULL;
81 m_nSelection = -1;
82}
83
84// default for dynamic class
85wxNotebook::wxNotebook()
86{
87 Init();
88}
89
90// the same arguments as for wxControl
91wxNotebook::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
104bool wxNotebook::Create(wxWindow *parent,
105 wxWindowID id,
106 const wxPoint& pos,
107 const wxSize& size,
108 long style,
109 const wxString& name)
110{
cdf1e714
DW
111 // base init
112 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
113 return FALSE;
114
115 // colors and font
fb46a9a6 116// TODO: m_backgroundColour = wxColour(GetSysColor(COLOR_BTNFACE));
cdf1e714
DW
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;
fb46a9a6 140
cdf1e714
DW
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 }
0e320a79 148
cdf1e714
DW
149 // Not all compilers recognise SetWindowFont
150 ::SendMessage(GetHwnd(), WM_SETFONT,
151 (WPARAM)::GetStockObject(DEFAULT_GUI_FONT), TRUE);
0e320a79 152
0e320a79 153
cdf1e714
DW
154 if ( parent != NULL )
155 parent->AddChild(this);
156*/
157 SubclassWin(m_hWnd);
0e320a79
DW
158
159 return FALSE;
160}
161
162// dtor
163wxNotebook::~wxNotebook()
164{
165}
166
167// ----------------------------------------------------------------------------
168// wxNotebook accessors
169// ----------------------------------------------------------------------------
170int wxNotebook::GetPageCount() const
171{
172 return m_aPages.Count();
173}
174
175int wxNotebook::GetRowCount() const
176{
177 // TODO
178 return 0;
179}
180
181int wxNotebook::SetSelection(int nPage)
182{
cdf1e714 183 wxCHECK_MSG( IS_VALID_PAGE(nPage), -1, wxT("notebook page out of range") );
0e320a79
DW
184
185 ChangePage(m_nSelection, nPage);
186
187 // TODO
188 return 0;
189}
190
191void 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
201bool wxNotebook::SetPageText(int nPage, const wxString& strText)
202{
cdf1e714 203 wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, wxT("notebook page out of range") );
0e320a79
DW
204
205 // TODO
206 return FALSE;
207}
208
209wxString wxNotebook::GetPageText(int nPage) const
210{
cdf1e714 211 wxCHECK_MSG( IS_VALID_PAGE(nPage), wxT(""), wxT("notebook page out of range") );
0e320a79
DW
212
213 // TODO
214 return wxString("");
215}
216
217int wxNotebook::GetPageImage(int nPage) const
218{
cdf1e714 219 wxCHECK_MSG( IS_VALID_PAGE(nPage), -1, wxT("notebook page out of range") );
0e320a79
DW
220
221 // TODO
222 return 0;
223}
224
225bool wxNotebook::SetPageImage(int nPage, int nImage)
226{
cdf1e714 227 wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, wxT("notebook page out of range") );
0e320a79
DW
228
229 // TODO
230 return FALSE;
231}
232
233void wxNotebook::SetImageList(wxImageList* imageList)
fb46a9a6 234{
0e320a79
DW
235 m_pImageList = imageList;
236 // TODO
237}
238
cdf1e714
DW
239void wxNotebook::SetTabSize(const wxSize& sz)
240{
241 // TODO
242}
243
0e320a79
DW
244// ----------------------------------------------------------------------------
245// wxNotebook operations
246// ----------------------------------------------------------------------------
247
248// remove one page from the notebook
249bool wxNotebook::DeletePage(int nPage)
250{
cdf1e714 251 wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, wxT("notebook page out of range") );
0e320a79
DW
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
262bool wxNotebook::RemovePage(int nPage)
263{
cdf1e714 264 wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, wxT("notebook page out of range") );
0e320a79
DW
265
266 m_aPages.Remove(nPage);
267
268 return TRUE;
269}
270
271// remove all pages
272bool 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
287bool 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
296bool 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
fb46a9a6 310 // some page must be selected: either this one or the first one if there is
0e320a79
DW
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)
326void 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);
7e99520b 350#if wxUSE_CONSTRAINTS
0e320a79
DW
351 if ( pPage->GetAutoLayout() )
352 pPage->Layout();
7e99520b
DW
353#endif //wxUSE_CONSTRAINTS
354
0e320a79
DW
355 }
356
357 // Processing continues to next OnSize
358 event.Skip();
359}
360
361void wxNotebook::OnSelChange(wxNotebookEvent& event)
362{
363 // is it our tab control?
364 if ( event.GetEventObject() == this )
cdf1e714
DW
365 {
366 int sel = event.GetOldSelection();
367 if ( sel != -1 )
368 m_aPages[sel]->Show(FALSE);
fb46a9a6 369
cdf1e714
DW
370 sel = event.GetSelection();
371 if ( sel != -1 )
372 {
373 wxNotebookPage *pPage = m_aPages[sel];
374 pPage->Show(TRUE);
375 pPage->SetFocus();
376 }
fb46a9a6 377
cdf1e714
DW
378 m_nSelection = sel;
379 }
0e320a79
DW
380 // we want to give others a chance to process this message as well
381 event.Skip();
382}
383
384void wxNotebook::OnSetFocus(wxFocusEvent& event)
385{
386 // set focus to the currently selected page if any
387 if ( m_nSelection != -1 )
388 m_aPages[m_nSelection]->SetFocus();
389
390 event.Skip();
391}
392
393void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
394{
395 if ( event.IsWindowChange() ) {
396 // change pages
397 AdvanceSelection(event.GetDirection());
398 }
399 else {
400 // pass to the parent
401 if ( GetParent() ) {
402 event.SetCurrentFocus(this);
403 GetParent()->ProcessEvent(event);
404 }
405 }
406}
407
408// ----------------------------------------------------------------------------
409// wxNotebook base class virtuals
410// ----------------------------------------------------------------------------
411
412// override these 2 functions to do nothing: everything is done in OnSize
413
414void wxNotebook::SetConstraintSizes(bool /* recurse */)
415{
7e99520b 416#if wxUSE_CONSTRAINTS
0e320a79
DW
417 // don't set the sizes of the pages - their correct size is not yet known
418 wxControl::SetConstraintSizes(FALSE);
7e99520b 419#endif
0e320a79
DW
420}
421
422bool wxNotebook::DoPhase(int /* nPhase */)
423{
424 return TRUE;
425}
426
cdf1e714 427bool wxNotebook::OS2OnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM* result)
0e320a79 428{
cdf1e714
DW
429 wxNotebookEvent event(wxEVT_NULL, m_windowId);
430//TODO:
431/*
432 NMHDR* hdr = (NMHDR *)lParam;
433 switch ( hdr->code ) {
434 case TCN_SELCHANGE:
435 event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED);
436 break;
437
438 case TCN_SELCHANGING:
439 event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING);
440 break;
441
442 default:
443 return wxControl::MSWOnNotify(idCtrl, lParam, result);
444 }
445*/
fb46a9a6 446// TODO: event.SetSelection(TabCtrl_GetCurSel(m_hwnd));
cdf1e714
DW
447 event.SetOldSelection(m_nSelection);
448 event.SetEventObject(this);
449 event.SetInt(idCtrl);
450
451 bool processed = GetEventHandler()->ProcessEvent(event);
fb46a9a6 452// TODO: *result = !event.IsAllowed();
cdf1e714 453 return processed;
0e320a79
DW
454}
455
456// ----------------------------------------------------------------------------
457// wxNotebook helper functions
458// ----------------------------------------------------------------------------
459
460// hide the currently active panel and show the new one
461void wxNotebook::ChangePage(int nOldSel, int nSel)
462{
cdf1e714
DW
463 // MT-FIXME should use a real semaphore
464 static bool s_bInsideChangePage = FALSE;
465
466 // when we call ProcessEvent(), our own OnSelChange() is called which calls
467 // this function - break the infinite loop
468 if ( s_bInsideChangePage )
469 return;
470
471 // it's not an error (the message may be generated by the tab control itself)
472 // and it may happen - just do nothing
473 if ( nSel == nOldSel )
474 return;
475
476 s_bInsideChangePage = TRUE;
477
478 wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, m_windowId);
479 event.SetSelection(nSel);
480 event.SetOldSelection(nOldSel);
481 event.SetEventObject(this);
482 if ( ProcessEvent(event) && !event.IsAllowed() )
483 {
484 // program doesn't allow the page change
485 s_bInsideChangePage = FALSE;
486 return;
0e320a79
DW
487 }
488
cdf1e714
DW
489 event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED);
490 ProcessEvent(event);
0e320a79 491
cdf1e714 492 s_bInsideChangePage = FALSE;
0e320a79
DW
493}
494