/[pcsx2_0.9.7]/branch/r3113_0.9.7_beta/3rdparty/wxWidgets/src/generic/notebook.cpp
ViewVC logotype

Annotation of /branch/r3113_0.9.7_beta/3rdparty/wxWidgets/src/generic/notebook.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 32 - (hide annotations) (download)
Tue Sep 7 03:29:01 2010 UTC (10 years ago) by william
File size: 19730 byte(s)
branching from upstream revision (http://pcsx2.googlecode.com/svn/trunk
): r3113 to
https://svn.netsolutions.dnsalias.com/websvn/ps2/pcsx2/pcsx2_0.9.7/branch/r3113_0.9.7_beta
1 william 31 ///////////////////////////////////////////////////////////////////////////////
2     // Name: src/generic/notebook.cpp
3     // Purpose: generic implementation of wxNotebook
4     // Author: Julian Smart
5     // Modified by:
6     // Created: 17/09/98
7     // RCS-ID: $Id: notebook.cpp 50855 2007-12-20 10:51:33Z JS $
8     // Copyright: (c) Julian Smart
9     // Licence: wxWindows licence
10     ///////////////////////////////////////////////////////////////////////////////
11    
12     // ============================================================================
13     // declarations
14     // ============================================================================
15    
16     // ----------------------------------------------------------------------------
17     // headers
18     // ----------------------------------------------------------------------------
19    
20     // For compilers that support precompilation, includes "wx.h".
21     #include "wx/wxprec.h"
22    
23     #ifdef __BORLANDC__
24     #pragma hdrstop
25     #endif
26    
27     #if wxUSE_NOTEBOOK
28    
29     #include "wx/notebook.h"
30    
31     #ifndef WX_PRECOMP
32     #include "wx/string.h"
33     #include "wx/log.h"
34     #include "wx/dcclient.h"
35     #include "wx/settings.h"
36     #endif
37    
38     #include "wx/imaglist.h"
39     #include "wx/generic/tabg.h"
40    
41     // ----------------------------------------------------------------------------
42     // macros
43     // ----------------------------------------------------------------------------
44    
45     // check that the page index is valid
46     #define IS_VALID_PAGE(nPage) ((nPage) < GetPageCount())
47    
48     // ----------------------------------------------------------------------------
49     // event table
50     // ----------------------------------------------------------------------------
51    
52     DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED)
53     DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING)
54    
55     BEGIN_EVENT_TABLE(wxNotebook, wxBookCtrlBase)
56     EVT_NOTEBOOK_PAGE_CHANGED(wxID_ANY, wxNotebook::OnSelChange)
57     EVT_SIZE(wxNotebook::OnSize)
58     EVT_PAINT(wxNotebook::OnPaint)
59     EVT_MOUSE_EVENTS(wxNotebook::OnMouseEvent)
60     EVT_SET_FOCUS(wxNotebook::OnSetFocus)
61     EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
62     END_EVENT_TABLE()
63    
64     IMPLEMENT_DYNAMIC_CLASS(wxNotebook, wxBookCtrlBase)
65     IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxCommandEvent)
66    
67     // ============================================================================
68     // implementation
69     // ============================================================================
70    
71     // ============================================================================
72     // Private class
73     // ============================================================================
74    
75     WX_DECLARE_HASH_MAP(int, wxNotebookPage*, wxIntegerHash, wxIntegerEqual,
76     wxIntToNotebookPageHashMap);
77    
78     WX_DECLARE_HASH_MAP(wxNotebookPage*, int, wxPointerHash, wxPointerEqual,
79     wxNotebookPageToIntHashMap);
80    
81     // This reuses wxTabView to draw the tabs.
82     class WXDLLEXPORT wxNotebookTabView: public wxTabView
83     {
84     DECLARE_DYNAMIC_CLASS(wxNotebookTabView)
85     public:
86     wxNotebookTabView(wxNotebook* notebook, long style = wxTAB_STYLE_DRAW_BOX | wxTAB_STYLE_COLOUR_INTERIOR);
87     virtual ~wxNotebookTabView(void);
88    
89     // Called when a tab is activated
90     virtual void OnTabActivate(int activateId, int deactivateId);
91     // Allows vetoing
92     virtual bool OnTabPreActivate(int activateId, int deactivateId);
93    
94     // map integer ids used by wxTabView to wxNotebookPage pointers
95     int GetId(wxNotebookPage *page);
96     wxNotebookPage *GetPage(int id) { return m_idToPage[id]; }
97    
98     protected:
99     wxNotebook* m_notebook;
100    
101     private:
102     wxIntToNotebookPageHashMap m_idToPage;
103     wxNotebookPageToIntHashMap m_pageToId;
104     int m_nextid;
105     };
106    
107     static int GetPageId(wxTabView *tabview, wxNotebookPage *page)
108     {
109     return wx_static_cast(wxNotebookTabView*, tabview)->GetId(page);
110     }
111    
112     // ----------------------------------------------------------------------------
113     // wxNotebook construction
114     // ----------------------------------------------------------------------------
115    
116     // common part of all ctors
117     void wxNotebook::Init()
118     {
119     m_tabView = (wxNotebookTabView*) NULL;
120     m_nSelection = -1;
121     }
122    
123     // default for dynamic class
124     wxNotebook::wxNotebook()
125     {
126     Init();
127     }
128    
129     // the same arguments as for wxControl
130     wxNotebook::wxNotebook(wxWindow *parent,
131     wxWindowID id,
132     const wxPoint& pos,
133     const wxSize& size,
134     long style,
135     const wxString& name)
136     {
137     Init();
138    
139     Create(parent, id, pos, size, style, name);
140     }
141    
142     // Create() function
143     bool wxNotebook::Create(wxWindow *parent,
144     wxWindowID id,
145     const wxPoint& pos,
146     const wxSize& size,
147     long style,
148     const wxString& name)
149     {
150     // base init
151     SetName(name);
152    
153     if ( (style & wxBK_ALIGN_MASK) == wxBK_DEFAULT )
154     style |= wxBK_TOP;
155    
156     m_windowId = id == wxID_ANY ? NewControlId() : id;
157    
158     if (!wxControl::Create(parent, id, pos, size, style|wxNO_BORDER, wxDefaultValidator, name))
159     return false;
160    
161     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
162    
163     SetTabView(new wxNotebookTabView(this));
164    
165     return true;
166     }
167    
168     // dtor
169     wxNotebook::~wxNotebook()
170     {
171     delete m_tabView;
172     }
173    
174     // ----------------------------------------------------------------------------
175     // wxNotebook accessors
176     // ----------------------------------------------------------------------------
177     int wxNotebook::GetRowCount() const
178     {
179     // TODO
180     return 0;
181     }
182    
183     int wxNotebook::SetSelection(size_t nPage)
184     {
185     wxASSERT( IS_VALID_PAGE(nPage) );
186    
187     wxNotebookPage* pPage = GetPage(nPage);
188    
189     m_tabView->SetTabSelection(GetPageId(m_tabView, pPage));
190    
191     // TODO
192     return 0;
193     }
194    
195     int wxNotebook::ChangeSelection(size_t nPage)
196     {
197     // FIXME: currently it does generate events too
198     return SetSelection(nPage);
199     }
200    
201     #if 0
202     void wxNotebook::AdvanceSelection(bool bForward)
203     {
204     int nSel = GetSelection();
205     int nMax = GetPageCount() - 1;
206     if ( bForward )
207     SetSelection(nSel == nMax ? 0 : nSel + 1);
208     else
209     SetSelection(nSel == 0 ? nMax : nSel - 1);
210     }
211     #endif
212    
213     bool wxNotebook::SetPageText(size_t nPage, const wxString& strText)
214     {
215     wxASSERT( IS_VALID_PAGE(nPage) );
216    
217     wxNotebookPage* page = GetPage(nPage);
218     if (page)
219     {
220     m_tabView->SetTabText(GetPageId(m_tabView, page), strText);
221     Refresh();
222     return true;
223     }
224    
225     return false;
226     }
227    
228     wxString wxNotebook::GetPageText(size_t nPage) const
229     {
230     wxASSERT( IS_VALID_PAGE(nPage) );
231    
232     wxNotebookPage* page = ((wxNotebook*)this)->GetPage(nPage);
233     if (page)
234     return m_tabView->GetTabText(GetPageId(m_tabView, page));
235     else
236     return wxEmptyString;
237     }
238    
239     int wxNotebook::GetPageImage(size_t WXUNUSED_UNLESS_DEBUG(nPage)) const
240     {
241     wxASSERT( IS_VALID_PAGE(nPage) );
242    
243     // TODO
244     return 0;
245     }
246    
247     bool wxNotebook::SetPageImage(size_t WXUNUSED_UNLESS_DEBUG(nPage),
248     int WXUNUSED(nImage))
249     {
250     wxASSERT( IS_VALID_PAGE(nPage) );
251    
252     // TODO
253     return false;
254     }
255    
256     // set the size (the same for all pages)
257     void wxNotebook::SetPageSize(const wxSize& WXUNUSED(size))
258     {
259     // TODO
260     }
261    
262     // set the padding between tabs (in pixels)
263     void wxNotebook::SetPadding(const wxSize& WXUNUSED(padding))
264     {
265     // TODO
266     }
267    
268     // set the size of the tabs for wxNB_FIXEDWIDTH controls
269     void wxNotebook::SetTabSize(const wxSize& WXUNUSED(sz))
270     {
271     // TODO
272     }
273    
274     // ----------------------------------------------------------------------------
275     // wxNotebook operations
276     // ----------------------------------------------------------------------------
277    
278     // remove one page from the notebook and delete it
279     bool wxNotebook::DeletePage(size_t nPage)
280     {
281     wxCHECK( IS_VALID_PAGE(nPage), false );
282    
283     if (m_nSelection != -1)
284     {
285     m_pages[m_nSelection]->Show(false);
286     m_pages[m_nSelection]->Lower();
287     }
288    
289     wxNotebookPage* pPage = GetPage(nPage);
290    
291     m_tabView->RemoveTab(GetPageId(m_tabView, pPage));
292    
293     m_pages.Remove(pPage);
294     delete pPage;
295    
296     if (m_pages.GetCount() == 0)
297     {
298     m_nSelection = -1;
299     m_tabView->SetTabSelection(-1, false);
300     }
301     else if (m_nSelection > -1)
302     {
303     m_nSelection = -1;
304    
305     m_tabView->SetTabSelection(GetPageId(m_tabView, GetPage(0)), false);
306    
307     if (m_nSelection != 0)
308     ChangePage(-1, 0);
309     }
310    
311     RefreshLayout(false);
312    
313     return true;
314     }
315    
316     bool wxNotebook::DeletePage(wxNotebookPage* page)
317     {
318     int pagePos = FindPagePosition(page);
319     if (pagePos > -1)
320     return DeletePage(pagePos);
321     else
322     return false;
323     }
324    
325     bool wxNotebook::RemovePage(size_t nPage)
326     {
327     return DoRemovePage(nPage) != NULL;
328     }
329    
330     // remove one page from the notebook
331     wxWindow* wxNotebook::DoRemovePage(size_t nPage)
332     {
333     wxCHECK( IS_VALID_PAGE(nPage), NULL );
334    
335     m_pages[nPage]->Show(false);
336     // m_pages[nPage]->Lower();
337    
338     wxNotebookPage* pPage = GetPage(nPage);
339    
340     m_tabView->RemoveTab(GetPageId(m_tabView, pPage));
341    
342     m_pages.Remove(pPage);
343    
344     if (m_pages.GetCount() == 0)
345     {
346     m_nSelection = -1;
347     m_tabView->SetTabSelection(-1, true);
348     }
349     else if (m_nSelection > -1)
350     {
351     // Only change the selection if the page we
352     // deleted was the selection.
353     if (nPage == (size_t)m_nSelection)
354     {
355     m_nSelection = -1;
356     // Select the first tab. Generates a ChangePage.
357     m_tabView->SetTabSelection(0, true);
358     }
359     else
360     {
361     // We must adjust which tab we think is selected.
362     // If greater than the page we deleted, it must be moved down
363     // a notch.
364     if (size_t(m_nSelection) > nPage)
365     m_nSelection -- ;
366     }
367     }
368    
369     RefreshLayout(false);
370    
371     return pPage;
372     }
373    
374     bool wxNotebook::RemovePage(wxNotebookPage* page)
375     {
376     int pagePos = FindPagePosition(page);
377     if (pagePos > -1)
378     return RemovePage(pagePos);
379     else
380     return false;
381     }
382    
383     // Find the position of the wxNotebookPage, -1 if not found.
384     int wxNotebook::FindPagePosition(wxNotebookPage* page) const
385     {
386     size_t nPageCount = GetPageCount();
387     size_t nPage;
388     for ( nPage = 0; nPage < nPageCount; nPage++ )
389     if (m_pages[nPage] == page)
390     return nPage;
391     return -1;
392     }
393    
394     // remove all pages
395     bool wxNotebook::DeleteAllPages()
396     {
397     m_tabView->ClearTabs(true);
398    
399     size_t nPageCount = GetPageCount();
400     size_t nPage;
401     for ( nPage = 0; nPage < nPageCount; nPage++ )
402     delete m_pages[nPage];
403    
404     m_pages.Clear();
405    
406     return true;
407     }
408    
409     // same as AddPage() but does it at given position
410     bool wxNotebook::InsertPage(size_t nPage,
411     wxNotebookPage *pPage,
412     const wxString& strText,
413     bool bSelect,
414     int WXUNUSED(imageId))
415     {
416     wxASSERT( pPage != NULL );
417     wxCHECK( IS_VALID_PAGE(nPage) || nPage == GetPageCount(), false );
418    
419     m_tabView->AddTab(GetPageId(m_tabView, pPage), strText);
420    
421     if (!bSelect)
422     pPage->Show(false);
423    
424     // save the pointer to the page
425     m_pages.Insert(pPage, nPage);
426    
427     if (bSelect)
428     {
429     // This will cause ChangePage to be called, via OnSelPage
430    
431     m_tabView->SetTabSelection(GetPageId(m_tabView, pPage), true);
432     }
433    
434     // some page must be selected: either this one or the first one if there is
435     // still no selection
436     if ( m_nSelection == -1 )
437     ChangePage(-1, 0);
438    
439     RefreshLayout(false);
440    
441     return true;
442     }
443    
444     // ----------------------------------------------------------------------------
445     // wxNotebook callbacks
446     // ----------------------------------------------------------------------------
447    
448     // @@@ OnSize() is used for setting the font when it's called for the first
449     // time because doing it in ::Create() doesn't work (for unknown reasons)
450     void wxNotebook::OnSize(wxSizeEvent& event)
451     {
452     static bool s_bFirstTime = true;
453     if ( s_bFirstTime ) {
454     // TODO: any first-time-size processing.
455     s_bFirstTime = false;
456     }
457    
458     RefreshLayout();
459    
460     // Processing continues to next OnSize
461     event.Skip();
462     }
463    
464     // This was supposed to cure the non-display of the notebook
465     // until the user resizes the window.
466     // What's going on?
467     void wxNotebook::OnInternalIdle()
468     {
469     wxWindow::OnInternalIdle();
470    
471     #if 0
472     static bool s_bFirstTime = true;
473     if ( s_bFirstTime ) {
474     /*
475     wxSize sz(GetSize());
476     sz.x ++;
477     SetSize(sz);
478     sz.x --;
479     SetSize(sz);
480     */
481    
482     /*
483     wxSize sz(GetSize());
484     wxSizeEvent sizeEvent(sz, GetId());
485     sizeEvent.SetEventObject(this);
486     GetEventHandler()->ProcessEvent(sizeEvent);
487     Refresh();
488     */
489     s_bFirstTime = false;
490     }
491     #endif
492     }
493    
494     // Implementation: calculate the layout of the view rect
495     // and resize the children if required
496     bool wxNotebook::RefreshLayout(bool force)
497     {
498     if (m_tabView)
499     {
500     wxRect oldRect = m_tabView->GetViewRect();
501    
502     int cw, ch;
503     GetClientSize(& cw, & ch);
504    
505     int tabHeight = m_tabView->GetTotalTabHeight();
506     wxRect rect;
507     rect.x = 4;
508     rect.y = tabHeight + 4;
509     rect.width = cw - 8;
510     rect.height = ch - 4 - rect.y ;
511    
512     m_tabView->SetViewRect(rect);
513    
514     m_tabView->LayoutTabs();
515    
516     // Need to do it a 2nd time to get the tab height with
517     // the new view width, since changing the view width changes the
518     // tab layout.
519     tabHeight = m_tabView->GetTotalTabHeight();
520     rect.x = 4;
521     rect.y = tabHeight + 4;
522     rect.width = cw - 8;
523     rect.height = ch - 4 - rect.y ;
524    
525     m_tabView->SetViewRect(rect);
526    
527     m_tabView->LayoutTabs();
528    
529     if (!force && (rect == oldRect))
530     return false;
531    
532     // fit the notebook page to the tab control's display area
533    
534     size_t nCount = m_pages.Count();
535     for ( size_t nPage = 0; nPage < nCount; nPage++ ) {
536     wxNotebookPage *pPage = m_pages[nPage];
537     wxRect clientRect = GetAvailableClientSize();
538     if (pPage->IsShown())
539     {
540     pPage->SetSize(clientRect.x, clientRect.y, clientRect.width, clientRect.height);
541     if ( pPage->GetAutoLayout() )
542     pPage->Layout();
543     }
544     }
545     Refresh();
546     }
547     return true;
548     }
549    
550     void wxNotebook::OnSelChange(wxNotebookEvent& event)
551     {
552     // is it our tab control?
553     if ( event.GetEventObject() == this )
554     {
555     if (event.GetSelection() != m_nSelection)
556     ChangePage(event.GetOldSelection(), event.GetSelection());
557     }
558    
559     // we want to give others a chance to process this message as well
560     event.Skip();
561     }
562    
563     void wxNotebook::OnSetFocus(wxFocusEvent& event)
564     {
565     // set focus to the currently selected page if any
566     if ( m_nSelection != -1 )
567     m_pages[m_nSelection]->SetFocus();
568    
569     event.Skip();
570     }
571    
572     void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
573     {
574     if ( event.IsWindowChange() ) {
575     // change pages
576     AdvanceSelection(event.GetDirection());
577     }
578     else {
579     // pass to the parent
580     if ( GetParent() ) {
581     event.SetCurrentFocus(this);
582     GetParent()->ProcessEvent(event);
583     }
584     }
585     }
586    
587     // ----------------------------------------------------------------------------
588     // wxNotebook base class virtuals
589     // ----------------------------------------------------------------------------
590    
591     // override these 2 functions to do nothing: everything is done in OnSize
592    
593     void wxNotebook::SetConstraintSizes(bool /* recurse */)
594     {
595     // don't set the sizes of the pages - their correct size is not yet known
596     wxControl::SetConstraintSizes(false);
597     }
598    
599     bool wxNotebook::DoPhase(int /* nPhase */)
600     {
601     return true;
602     }
603    
604     void wxNotebook::Command(wxCommandEvent& WXUNUSED(event))
605     {
606     wxFAIL_MSG(wxT("wxNotebook::Command not implemented"));
607     }
608    
609     // ----------------------------------------------------------------------------
610     // wxNotebook helper functions
611     // ----------------------------------------------------------------------------
612    
613     // hide the currently active panel and show the new one
614     void wxNotebook::ChangePage(int nOldSel, int nSel)
615     {
616     // cout << "ChangePage: " << nOldSel << ", " << nSel << "\n";
617     wxASSERT( nOldSel != nSel ); // impossible
618    
619     if ( nOldSel != -1 ) {
620     m_pages[nOldSel]->Show(false);
621     m_pages[nOldSel]->Lower();
622     }
623    
624     wxNotebookPage *pPage = m_pages[nSel];
625    
626     wxRect clientRect = GetAvailableClientSize();
627     pPage->SetSize(clientRect.x, clientRect.y, clientRect.width, clientRect.height);
628    
629     Refresh();
630    
631     pPage->Show(true);
632     pPage->Raise();
633     pPage->SetFocus();
634    
635     m_nSelection = nSel;
636     }
637    
638     void wxNotebook::OnMouseEvent(wxMouseEvent& event)
639     {
640     if (m_tabView)
641     m_tabView->OnEvent(event);
642     }
643    
644     void wxNotebook::OnPaint(wxPaintEvent& WXUNUSED(event) )
645     {
646     wxPaintDC dc(this);
647     if (m_tabView)
648     m_tabView->Draw(dc);
649     }
650    
651     wxSize wxNotebook::CalcSizeFromPage(const wxSize& sizePage) const
652     {
653     // MBN: since the total tab height is really a function of the
654     // width, this should really call
655     // GetTotalTabHeightPretendingWidthIs(), but the current
656     // implementation will suffice, provided the wxNotebook has been
657     // created with a sensible initial width.
658     return wxSize( sizePage.x + 12,
659     sizePage.y + m_tabView->GetTotalTabHeight() + 6 + 4 );
660     }
661    
662     wxRect wxNotebook::GetAvailableClientSize()
663     {
664     int cw, ch;
665     GetClientSize(& cw, & ch);
666    
667     int tabHeight = m_tabView->GetTotalTabHeight();
668    
669     // TODO: these margins should be configurable.
670     wxRect rect;
671     rect.x = 6;
672     rect.y = tabHeight + 6;
673     rect.width = cw - 12;
674     rect.height = ch - 4 - rect.y ;
675    
676     return rect;
677     }
678    
679     /*
680     * wxNotebookTabView
681     */
682    
683     IMPLEMENT_CLASS(wxNotebookTabView, wxTabView)
684    
685     wxNotebookTabView::wxNotebookTabView(wxNotebook *notebook, long style)
686     : wxTabView(style), m_nextid(1)
687     {
688     m_notebook = notebook;
689    
690     m_notebook->SetTabView(this);
691    
692     SetWindow(m_notebook);
693     }
694    
695     wxNotebookTabView::~wxNotebookTabView(void)
696     {
697     }
698    
699     int wxNotebookTabView::GetId(wxNotebookPage *page)
700     {
701     int& id = m_pageToId[page];
702    
703     if (!id)
704     {
705     id = m_nextid++;
706     m_idToPage[id] = page;
707     }
708    
709     return id;
710     }
711    
712     // Called when a tab is activated
713     void wxNotebookTabView::OnTabActivate(int activateId, int deactivateId)
714     {
715     if (!m_notebook)
716     return;
717    
718     wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, m_notebook->GetId());
719    
720     // Translate from wxTabView's ids (which aren't position-dependent)
721     // to wxNotebook's (which are).
722     wxNotebookPage* pActive = GetPage(activateId);
723     wxNotebookPage* pDeactive = GetPage(deactivateId);
724    
725     int activatePos = m_notebook->FindPagePosition(pActive);
726     int deactivatePos = m_notebook->FindPagePosition(pDeactive);
727    
728     event.SetEventObject(m_notebook);
729     event.SetSelection(activatePos);
730     event.SetOldSelection(deactivatePos);
731     m_notebook->GetEventHandler()->ProcessEvent(event);
732     }
733    
734     // Allows Vetoing
735     bool wxNotebookTabView::OnTabPreActivate(int activateId, int deactivateId)
736     {
737     bool retval = true;
738    
739     if (m_notebook)
740     {
741     wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, m_notebook->GetId());
742    
743     // Translate from wxTabView's ids (which aren't position-dependent)
744     // to wxNotebook's (which are).
745     wxNotebookPage* pActive = GetPage(activateId);
746     wxNotebookPage* pDeactive = GetPage(deactivateId);
747    
748     int activatePos = m_notebook->FindPagePosition(pActive);
749     int deactivatePos = m_notebook->FindPagePosition(pDeactive);
750    
751     event.SetEventObject(m_notebook);
752     event.SetSelection(activatePos);
753     event.SetOldSelection(deactivatePos);
754     if (m_notebook->GetEventHandler()->ProcessEvent(event))
755     {
756     retval = event.IsAllowed();
757     }
758     }
759     return retval;
760     }
761    
762     #endif // wxUSE_NOTEBOOK

  ViewVC Help
Powered by ViewVC 1.1.22