]> git.saurik.com Git - wxWidgets.git/blob - src/motif/notebook.cpp
Motif and other mods
[wxWidgets.git] / src / motif / notebook.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: notebook.cpp
3 // Purpose: implementation of wxNotebook
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 17/09/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
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/dcclient.h>
28
29 // ----------------------------------------------------------------------------
30 // macros
31 // ----------------------------------------------------------------------------
32
33 // check that the page index is valid
34 #define IS_VALID_PAGE(nPage) (((nPage) >= 0) && ((nPage) < GetPageCount()))
35
36 // ----------------------------------------------------------------------------
37 // event table
38 // ----------------------------------------------------------------------------
39
40 #if !USE_SHARED_LIBRARIES
41 BEGIN_EVENT_TABLE(wxNotebook, wxControl)
42 EVT_NOTEBOOK_PAGE_CHANGED(-1, wxNotebook::OnSelChange)
43 EVT_SIZE(wxNotebook::OnSize)
44 EVT_PAINT(wxNotebook::OnPaint)
45 EVT_MOUSE_EVENTS(wxNotebook::OnMouseEvent)
46 EVT_SET_FOCUS(wxNotebook::OnSetFocus)
47 EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
48 END_EVENT_TABLE()
49
50 IMPLEMENT_DYNAMIC_CLASS(wxNotebook, wxControl)
51 IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxCommandEvent)
52 #endif
53
54 // ============================================================================
55 // implementation
56 // ============================================================================
57
58 // ----------------------------------------------------------------------------
59 // wxNotebook construction
60 // ----------------------------------------------------------------------------
61
62 // common part of all ctors
63 void wxNotebook::Init()
64 {
65 m_tabView = (wxNotebookTabView*) NULL;
66 m_pImageList = NULL;
67 m_nSelection = -1;
68 }
69
70 // default for dynamic class
71 wxNotebook::wxNotebook()
72 {
73 Init();
74 }
75
76 // the same arguments as for wxControl
77 wxNotebook::wxNotebook(wxWindow *parent,
78 wxWindowID id,
79 const wxPoint& pos,
80 const wxSize& size,
81 long style,
82 const wxString& name)
83 {
84 Init();
85
86 Create(parent, id, pos, size, style, name);
87 }
88
89 // Create() function
90 bool wxNotebook::Create(wxWindow *parent,
91 wxWindowID id,
92 const wxPoint& pos,
93 const wxSize& size,
94 long style,
95 const wxString& name)
96 {
97 // base init
98 SetName(name);
99 SetParent(parent);
100
101 m_windowId = id == -1 ? NewControlId() : id;
102
103 // style
104 m_windowStyle = style;
105
106 if ( parent != NULL )
107 parent->AddChild(this);
108
109 // It's like a normal window...
110 if (!wxWindow::Create(parent, id, pos, size, style, name))
111 return FALSE;
112
113 SetTabView(new wxNotebookTabView(this));
114
115 return TRUE;
116 }
117
118 // dtor
119 wxNotebook::~wxNotebook()
120 {
121 delete m_tabView;
122 }
123
124 // ----------------------------------------------------------------------------
125 // wxNotebook accessors
126 // ----------------------------------------------------------------------------
127 int wxNotebook::GetPageCount() const
128 {
129 return m_aPages.Count();
130 }
131
132 int wxNotebook::GetRowCount() const
133 {
134 // TODO
135 return 0;
136 }
137
138 int wxNotebook::SetSelection(int nPage)
139 {
140 wxASSERT( IS_VALID_PAGE(nPage) );
141
142 ChangePage(m_nSelection, nPage);
143
144 // TODO
145 return 0;
146 }
147
148 void wxNotebook::AdvanceSelection(bool bForward)
149 {
150 int nSel = GetSelection();
151 int nMax = GetPageCount() - 1;
152 if ( bForward )
153 SetSelection(nSel == nMax ? 0 : nSel + 1);
154 else
155 SetSelection(nSel == 0 ? nMax : nSel - 1);
156 }
157
158 bool wxNotebook::SetPageText(int nPage, const wxString& strText)
159 {
160 wxASSERT( IS_VALID_PAGE(nPage) );
161
162 // TODO
163 return FALSE;
164 }
165
166 wxString wxNotebook::GetPageText(int nPage) const
167 {
168 wxASSERT( IS_VALID_PAGE(nPage) );
169
170 // TODO
171 return wxString("");
172 }
173
174 int wxNotebook::GetPageImage(int nPage) const
175 {
176 wxASSERT( IS_VALID_PAGE(nPage) );
177
178 // TODO
179 return 0;
180 }
181
182 bool wxNotebook::SetPageImage(int nPage, int nImage)
183 {
184 wxASSERT( IS_VALID_PAGE(nPage) );
185
186 // TODO
187 return FALSE;
188 }
189
190 void wxNotebook::SetImageList(wxImageList* imageList)
191 {
192 m_pImageList = imageList;
193 // TODO
194 }
195
196 // ----------------------------------------------------------------------------
197 // wxNotebook operations
198 // ----------------------------------------------------------------------------
199
200 // remove one page from the notebook
201 bool wxNotebook::DeletePage(int nPage)
202 {
203 wxFAIL_MSG("Sorry, DeletePage not implemented for Motif wxNotebook because wxTabView doesn't support it.");
204 return FALSE;
205
206 /*
207 wxCHECK( IS_VALID_PAGE(nPage), FALSE );
208
209 // TODO: delete native widget page
210
211 delete m_aPages[nPage];
212 m_aPages.Remove(nPage);
213
214 return TRUE;
215 */
216 }
217
218 // remove all pages
219 bool wxNotebook::DeleteAllPages()
220 {
221 m_tabView->ClearTabs(TRUE);
222
223 int nPageCount = GetPageCount();
224 int nPage;
225 for ( nPage = 0; nPage < nPageCount; nPage++ )
226 delete m_aPages[nPage];
227
228 m_aPages.Clear();
229
230 return TRUE;
231 }
232
233 // add a page to the notebook
234 bool wxNotebook::AddPage(wxNotebookPage *pPage,
235 const wxString& strText,
236 bool bSelect,
237 int imageId)
238 {
239 return InsertPage(GetPageCount(), pPage, strText, bSelect, imageId);
240 }
241
242 // same as AddPage() but does it at given position
243 bool wxNotebook::InsertPage(int nPage,
244 wxNotebookPage *pPage,
245 const wxString& strText,
246 bool bSelect,
247 int imageId)
248 {
249 wxASSERT( pPage != NULL );
250 wxCHECK( IS_VALID_PAGE(nPage) || nPage == GetPageCount(), FALSE );
251
252 m_tabView->AddTab(nPage, strText);
253
254 /*
255 if (bSelect)
256 m_tabView->SetTabSelection(nPage, TRUE);
257 */
258
259 // save the pointer to the page
260 m_aPages.Insert(pPage, nPage);
261
262 // some page must be selected: either this one or the first one if there is
263 // still no selection
264 if ( bSelect )
265 m_nSelection = nPage;
266 else if ( m_nSelection == -1 )
267 m_nSelection = 0;
268
269 return TRUE;
270 }
271
272 // ----------------------------------------------------------------------------
273 // wxNotebook callbacks
274 // ----------------------------------------------------------------------------
275
276 // @@@ OnSize() is used for setting the font when it's called for the first
277 // time because doing it in ::Create() doesn't work (for unknown reasons)
278 void wxNotebook::OnSize(wxSizeEvent& event)
279 {
280 static bool s_bFirstTime = TRUE;
281 if ( s_bFirstTime ) {
282 // TODO: any first-time-size processing.
283 s_bFirstTime = FALSE;
284 }
285
286 if (m_tabView)
287 {
288 int cw, ch;
289 GetClientSize(& cw, & ch);
290
291 int tabHeight = m_tabView->GetTotalTabHeight();
292 wxRect rect;
293 rect.x = 4;
294 rect.y = tabHeight + 4;
295 rect.width = cw - 8;
296 rect.height = ch - 4 - rect.y ;
297
298 m_tabView->SetViewRect(rect);
299
300 m_tabView->Layout();
301
302 // Need to do it a 2nd time to get the tab height with
303 // the new view width, since changing the view width changes the
304 // tab layout.
305 tabHeight = m_tabView->GetTotalTabHeight();
306 rect.x = 4;
307 rect.y = tabHeight + 4;
308 rect.width = cw - 8;
309 rect.height = ch - 4 - rect.y ;
310
311 m_tabView->SetViewRect(rect);
312
313 m_tabView->Layout();
314
315 // emulate page change (it's esp. important to do it first time because
316 // otherwise our page would stay invisible)
317 int nSel = m_nSelection;
318 m_nSelection = -1;
319 SetSelection(nSel);
320
321 // fit the notebook page to the tab control's display area
322
323 unsigned int nCount = m_aPages.Count();
324 for ( unsigned int nPage = 0; nPage < nCount; nPage++ ) {
325 wxNotebookPage *pPage = m_aPages[nPage];
326 pPage->SetSize(rect.x + 2, rect.y + 2, rect.width - 2, rect.height - 2);
327 if ( pPage->GetAutoLayout() )
328 pPage->Layout();
329 }
330 Refresh();
331 }
332
333 // Processing continues to next OnSize
334 event.Skip();
335 }
336
337 void wxNotebook::OnSelChange(wxNotebookEvent& event)
338 {
339 // is it our tab control?
340 if ( event.GetEventObject() == this )
341 ChangePage(event.GetOldSelection(), event.GetSelection());
342
343 // we want to give others a chance to process this message as well
344 event.Skip();
345 }
346
347 void wxNotebook::OnSetFocus(wxFocusEvent& event)
348 {
349 // set focus to the currently selected page if any
350 if ( m_nSelection != -1 )
351 m_aPages[m_nSelection]->SetFocus();
352
353 event.Skip();
354 }
355
356 void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
357 {
358 if ( event.IsWindowChange() ) {
359 // change pages
360 AdvanceSelection(event.GetDirection());
361 }
362 else {
363 // pass to the parent
364 if ( GetParent() ) {
365 event.SetCurrentFocus(this);
366 GetParent()->ProcessEvent(event);
367 }
368 }
369 }
370
371 // ----------------------------------------------------------------------------
372 // wxNotebook base class virtuals
373 // ----------------------------------------------------------------------------
374
375 // override these 2 functions to do nothing: everything is done in OnSize
376
377 void wxNotebook::SetConstraintSizes(bool /* recurse */)
378 {
379 // don't set the sizes of the pages - their correct size is not yet known
380 wxControl::SetConstraintSizes(FALSE);
381 }
382
383 bool wxNotebook::DoPhase(int /* nPhase */)
384 {
385 return TRUE;
386 }
387
388 void wxNotebook::Command(wxCommandEvent& event)
389 {
390 wxFAIL_MSG("wxNotebook::Command not implemented");
391 }
392
393 // ----------------------------------------------------------------------------
394 // wxNotebook helper functions
395 // ----------------------------------------------------------------------------
396
397 // hide the currently active panel and show the new one
398 void wxNotebook::ChangePage(int nOldSel, int nSel)
399 {
400 wxASSERT( nOldSel != nSel ); // impossible
401
402 if ( nOldSel != -1 ) {
403 m_aPages[nOldSel]->Show(FALSE);
404 }
405
406 wxNotebookPage *pPage = m_aPages[nSel];
407 pPage->Show(TRUE);
408 pPage->SetFocus();
409
410 m_nSelection = nSel;
411 }
412
413 void wxNotebook::ChangeFont(bool keepOriginalSize)
414 {
415 wxWindow::ChangeFont(keepOriginalSize);
416 }
417
418 void wxNotebook::ChangeBackgroundColour()
419 {
420 wxWindow::ChangeBackgroundColour();
421 }
422
423 void wxNotebook::ChangeForegroundColour()
424 {
425 wxWindow::ChangeForegroundColour();
426 }
427
428 void wxNotebook::OnMouseEvent(wxMouseEvent& event)
429 {
430 if (m_tabView)
431 m_tabView->OnEvent(event);
432 }
433
434 void wxNotebook::OnPaint(wxPaintEvent& WXUNUSED(event) )
435 {
436 wxPaintDC dc(this);
437 if (m_tabView)
438 m_tabView->Draw(dc);
439 }
440
441 /*
442 * wxNotebookTabView
443 */
444
445 IMPLEMENT_CLASS(wxNotebookTabView, wxTabView)
446
447 wxNotebookTabView::wxNotebookTabView(wxNotebook *notebook, long style): wxTabView(style)
448 {
449 m_notebook = notebook;
450
451 // m_currentWindow = (wxWindow *) NULL;
452
453 m_notebook->SetTabView(this);
454
455 SetWindow(m_notebook);
456 }
457
458 wxNotebookTabView::~wxNotebookTabView(void)
459 {
460 // ClearWindows(TRUE);
461 }
462
463 // Called when a tab is activated
464 void wxNotebookTabView::OnTabActivate(int activateId, int deactivateId)
465 {
466 if (!m_notebook)
467 return;
468
469 wxWindow *oldWindow = ((deactivateId == -1) ? 0 : m_notebook->GetPage(deactivateId));
470 wxWindow *newWindow = m_notebook->GetPage(activateId);
471
472 if (oldWindow)
473 oldWindow->Show(FALSE);
474 if (newWindow)
475 newWindow->Show(TRUE);
476
477 m_notebook->Refresh();
478 }
479
480 #if 0
481 void wxNotebookTabView::AddTabWindow(int id, wxWindow *window)
482 {
483 m_tabWindows.Append((long)id, window);
484 window->Show(FALSE);
485 }
486
487 wxWindow *wxNotebookTabView::GetTabWindow(int id) const
488 {
489 wxNode *node = m_tabWindows.Find((long)id);
490 if (!node)
491 return (wxWindow *) NULL;
492 return (wxWindow *)node->Data();
493 }
494
495 void wxNotebookTabView::ClearWindows(bool deleteWindows)
496 {
497 if (deleteWindows)
498 m_tabWindows.DeleteContents(TRUE);
499 m_tabWindows.Clear();
500 m_tabWindows.DeleteContents(FALSE);
501 }
502
503 void wxNotebookTabView::ShowWindowForTab(int id)
504 {
505 wxWindow *newWindow = GetTabWindow(id);
506 if (newWindow == m_currentWindow)
507 return;
508 if (m_currentWindow)
509 m_currentWindow->Show(FALSE);
510 newWindow->Show(TRUE);
511 newWindow->Refresh();
512 }
513 #endif
514