/[pcsx2_0.9.7]/trunk/3rdparty/wxWidgets/src/common/bookctrl.cpp
ViewVC logotype

Annotation of /trunk/3rdparty/wxWidgets/src/common/bookctrl.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years, 4 months ago) by william
File size: 13825 byte(s)
committing r3113 initial commit again...
1 william 31 ///////////////////////////////////////////////////////////////////////////////
2     // Name: src/common/bookctrl.cpp
3     // Purpose: wxBookCtrlBase implementation
4     // Author: Vadim Zeitlin
5     // Modified by:
6     // Created: 19.08.03
7     // RCS-ID: $Id: bookctrl.cpp 53783 2008-05-27 14:15:14Z SC $
8     // Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
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_BOOKCTRL
28    
29     #include "wx/imaglist.h"
30    
31     #include "wx/bookctrl.h"
32    
33     // ============================================================================
34     // implementation
35     // ============================================================================
36    
37     // ----------------------------------------------------------------------------
38     // event table
39     // ----------------------------------------------------------------------------
40    
41     IMPLEMENT_ABSTRACT_CLASS(wxBookCtrlBase, wxControl)
42    
43     BEGIN_EVENT_TABLE(wxBookCtrlBase, wxControl)
44     EVT_SIZE(wxBookCtrlBase::OnSize)
45     #if wxUSE_HELP
46     EVT_HELP(wxID_ANY, wxBookCtrlBase::OnHelp)
47     #endif // wxUSE_HELP
48     END_EVENT_TABLE()
49    
50     // ----------------------------------------------------------------------------
51     // constructors and destructors
52     // ----------------------------------------------------------------------------
53    
54     void wxBookCtrlBase::Init()
55     {
56     m_bookctrl = NULL;
57     m_imageList = NULL;
58     m_ownsImageList = false;
59     m_fitToCurrentPage = false;
60    
61     #if defined(__WXWINCE__)
62     m_internalBorder = 1;
63     #else
64     m_internalBorder = 5;
65     #endif
66    
67     m_controlMargin = 0;
68     m_controlSizer = NULL;
69     }
70    
71     bool
72     wxBookCtrlBase::Create(wxWindow *parent,
73     wxWindowID id,
74     const wxPoint& pos,
75     const wxSize& size,
76     long style,
77     const wxString& name)
78     {
79     return wxControl::Create
80     (
81     parent,
82     id,
83     pos,
84     size,
85     style,
86     wxDefaultValidator,
87     name
88     );
89     }
90    
91     wxBookCtrlBase::~wxBookCtrlBase()
92     {
93     if ( m_ownsImageList )
94     {
95     // may be NULL, ok
96     delete m_imageList;
97     }
98     }
99    
100     // ----------------------------------------------------------------------------
101     // image list
102     // ----------------------------------------------------------------------------
103    
104     void wxBookCtrlBase::SetImageList(wxImageList *imageList)
105     {
106     if ( m_ownsImageList )
107     {
108     // may be NULL, ok
109     delete m_imageList;
110    
111     m_ownsImageList = false;
112     }
113    
114     m_imageList = imageList;
115     }
116    
117     void wxBookCtrlBase::AssignImageList(wxImageList* imageList)
118     {
119     SetImageList(imageList);
120    
121     m_ownsImageList = true;
122     }
123    
124     // ----------------------------------------------------------------------------
125     // geometry
126     // ----------------------------------------------------------------------------
127    
128     void wxBookCtrlBase::DoInvalidateBestSize()
129     {
130     // notice that it is not necessary to invalidate our own best size
131     // explicitly if we have m_bookctrl as it will already invalidate the best
132     // size of its parent when its own size is invalidated and its parent is
133     // this control
134     if ( m_bookctrl )
135     m_bookctrl->InvalidateBestSize();
136     else
137     wxControl::InvalidateBestSize();
138     }
139    
140     void wxBookCtrlBase::SetPageSize(const wxSize& size)
141     {
142     SetClientSize(CalcSizeFromPage(size));
143     }
144    
145     wxSize wxBookCtrlBase::DoGetBestSize() const
146     {
147     wxSize bestSize;
148    
149     // iterate over all pages, get the largest width and height
150     const size_t nCount = m_pages.size();
151     for ( size_t nPage = 0; nPage < nCount; nPage++ )
152     {
153     const wxWindow * const pPage = m_pages[nPage];
154     if( pPage )
155     {
156     wxSize childBestSize(pPage->GetBestSize());
157    
158     if ( childBestSize.x > bestSize.x )
159     bestSize.x = childBestSize.x;
160    
161     if ( childBestSize.y > bestSize.y )
162     bestSize.y = childBestSize.y;
163     }
164     }
165    
166     if (m_fitToCurrentPage && GetCurrentPage())
167     bestSize = GetCurrentPage()->GetBestSize();
168    
169     // convert display area to window area, adding the size necessary for the
170     // tabs
171     wxSize best = CalcSizeFromPage(bestSize);
172     CacheBestSize(best);
173     return best;
174     }
175    
176     wxRect wxBookCtrlBase::GetPageRect() const
177     {
178     const wxSize size = GetControllerSize();
179    
180     wxPoint pt;
181     wxRect rectPage(pt, GetClientSize());
182    
183     switch ( GetWindowStyle() & wxBK_ALIGN_MASK )
184     {
185     default:
186     wxFAIL_MSG( _T("unexpected alignment") );
187     // fall through
188    
189     case wxBK_TOP:
190     rectPage.y = size.y + GetInternalBorder();
191     // fall through
192    
193     case wxBK_BOTTOM:
194     rectPage.height -= size.y + GetInternalBorder();
195     if (rectPage.height < 0)
196     rectPage.height = 0;
197     break;
198    
199     case wxBK_LEFT:
200     rectPage.x = size.x + GetInternalBorder();
201     // fall through
202    
203     case wxBK_RIGHT:
204     rectPage.width -= size.x + GetInternalBorder();
205     if (rectPage.width < 0)
206     rectPage.width = 0;
207     break;
208     }
209    
210     return rectPage;
211     }
212    
213     // Lay out controls
214     void wxBookCtrlBase::DoSize()
215     {
216     if ( !m_bookctrl )
217     {
218     // we're not fully created yet or OnSize() should be hidden by derived class
219     return;
220     }
221    
222     if (GetSizer())
223     Layout();
224     else
225     {
226     // resize controller and the page area to fit inside our new size
227     const wxSize sizeClient( GetClientSize() ),
228     sizeBorder( m_bookctrl->GetSize() - m_bookctrl->GetClientSize() ),
229     sizeCtrl( GetControllerSize() );
230    
231     m_bookctrl->SetClientSize( sizeCtrl.x - sizeBorder.x, sizeCtrl.y - sizeBorder.y );
232     // if this changes the visibility of the scrollbars the best size changes, relayout in this case
233     wxSize sizeCtrl2 = GetControllerSize();
234     if ( sizeCtrl != sizeCtrl2 )
235     {
236     wxSize sizeBorder2 = m_bookctrl->GetSize() - m_bookctrl->GetClientSize();
237     m_bookctrl->SetClientSize( sizeCtrl2.x - sizeBorder2.x, sizeCtrl2.y - sizeBorder2.y );
238     }
239    
240     const wxSize sizeNew = m_bookctrl->GetSize();
241     wxPoint posCtrl;
242     switch ( GetWindowStyle() & wxBK_ALIGN_MASK )
243     {
244     default:
245     wxFAIL_MSG( _T("unexpected alignment") );
246     // fall through
247    
248     case wxBK_TOP:
249     case wxBK_LEFT:
250     // posCtrl is already ok
251     break;
252    
253     case wxBK_BOTTOM:
254     posCtrl.y = sizeClient.y - sizeNew.y;
255     break;
256    
257     case wxBK_RIGHT:
258     posCtrl.x = sizeClient.x - sizeNew.x;
259     break;
260     }
261    
262     if ( m_bookctrl->GetPosition() != posCtrl )
263     m_bookctrl->Move(posCtrl);
264     }
265    
266     // resize all pages to fit the new control size
267     const wxRect pageRect = GetPageRect();
268     const unsigned pagesCount = m_pages.Count();
269     for ( unsigned int i = 0; i < pagesCount; ++i )
270     {
271     wxWindow * const page = m_pages[i];
272     if ( !page )
273     {
274     wxASSERT_MSG( AllowNullPage(),
275     _T("Null page in a control that does not allow null pages?") );
276     continue;
277     }
278    
279     page->SetSize(pageRect);
280     }
281     }
282    
283     void wxBookCtrlBase::OnSize(wxSizeEvent& event)
284     {
285     event.Skip();
286    
287     DoSize();
288     }
289    
290     wxSize wxBookCtrlBase::GetControllerSize() const
291     {
292     if(!m_bookctrl)
293     return wxSize(0,0);
294    
295     const wxSize sizeClient = GetClientSize(),
296     sizeBorder = m_bookctrl->GetSize() - m_bookctrl->GetClientSize(),
297     sizeCtrl = m_bookctrl->GetBestSize() + sizeBorder;
298    
299     wxSize size;
300    
301     if ( IsVertical() )
302     {
303     size.x = sizeClient.x;
304     size.y = sizeCtrl.y;
305     }
306     else // left/right aligned
307     {
308     size.x = sizeCtrl.x;
309     size.y = sizeClient.y;
310     }
311    
312     return size;
313     }
314    
315     // ----------------------------------------------------------------------------
316     // miscellaneous stuff
317     // ----------------------------------------------------------------------------
318    
319     #if wxUSE_HELP
320    
321     void wxBookCtrlBase::OnHelp(wxHelpEvent& event)
322     {
323     // determine where does this even originate from to avoid redirecting it
324     // back to the page which generated it (resulting in an infinite loop)
325    
326     // notice that we have to check in the hard(er) way instead of just testing
327     // if the event object == this because the book control can have other
328     // subcontrols inside it (e.g. wxSpinButton in case of a notebook in wxUniv)
329     wxWindow *source = wxStaticCast(event.GetEventObject(), wxWindow);
330     while ( source && source != this && source->GetParent() != this )
331     {
332     source = source->GetParent();
333     }
334    
335     if ( source && m_pages.Index(source) == wxNOT_FOUND )
336     {
337     // this event is for the book control itself, redirect it to the
338     // corresponding page
339     wxWindow *page = NULL;
340    
341     if ( event.GetOrigin() == wxHelpEvent::Origin_HelpButton )
342     {
343     // show help for the page under the mouse
344     const int pagePos = HitTest(ScreenToClient(event.GetPosition()));
345    
346     if ( pagePos != wxNOT_FOUND)
347     {
348     page = GetPage((size_t)pagePos);
349     }
350     }
351     else // event from keyboard or unknown source
352     {
353     // otherwise show the current page help
354     page = GetCurrentPage();
355     }
356    
357     if ( page )
358     {
359     // change event object to the page to avoid infinite recursion if
360     // we get this event ourselves if the page doesn't handle it
361     event.SetEventObject(page);
362    
363     if ( page->GetEventHandler()->ProcessEvent(event) )
364     {
365     // don't call event.Skip()
366     return;
367     }
368     }
369     }
370     //else: event coming from one of our pages already
371    
372     event.Skip();
373     }
374    
375     #endif // wxUSE_HELP
376    
377     // ----------------------------------------------------------------------------
378     // pages management
379     // ----------------------------------------------------------------------------
380    
381     bool
382     wxBookCtrlBase::InsertPage(size_t nPage,
383     wxWindow *page,
384     const wxString& WXUNUSED(text),
385     bool WXUNUSED(bSelect),
386     int WXUNUSED(imageId))
387     {
388     wxCHECK_MSG( page || AllowNullPage(), false,
389     _T("NULL page in wxBookCtrlBase::InsertPage()") );
390     wxCHECK_MSG( nPage <= m_pages.size(), false,
391     _T("invalid page index in wxBookCtrlBase::InsertPage()") );
392    
393     m_pages.Insert(page, nPage);
394     if ( page )
395     page->SetSize(GetPageRect());
396    
397     DoInvalidateBestSize();
398    
399     return true;
400     }
401    
402     bool wxBookCtrlBase::DeletePage(size_t nPage)
403     {
404     wxWindow *page = DoRemovePage(nPage);
405     if ( !(page || AllowNullPage()) )
406     return false;
407    
408     // delete NULL is harmless
409     delete page;
410    
411     return true;
412     }
413    
414     wxWindow *wxBookCtrlBase::DoRemovePage(size_t nPage)
415     {
416     wxCHECK_MSG( nPage < m_pages.size(), NULL,
417     _T("invalid page index in wxBookCtrlBase::DoRemovePage()") );
418    
419     wxWindow *pageRemoved = m_pages[nPage];
420     m_pages.RemoveAt(nPage);
421     DoInvalidateBestSize();
422    
423     return pageRemoved;
424     }
425    
426     int wxBookCtrlBase::GetNextPage(bool forward) const
427     {
428     int nPage;
429    
430     int nMax = GetPageCount();
431     if ( nMax-- ) // decrement it to get the last valid index
432     {
433     int nSel = GetSelection();
434    
435     // change selection wrapping if it becomes invalid
436     nPage = forward ? nSel == nMax ? 0
437     : nSel + 1
438     : nSel == 0 ? nMax
439     : nSel - 1;
440     }
441     else // notebook is empty, no next page
442     {
443     nPage = wxNOT_FOUND;
444     }
445    
446     return nPage;
447     }
448    
449     int wxBookCtrlBase::DoSetSelection(size_t n, int flags)
450     {
451     wxCHECK_MSG( n < GetPageCount(), wxNOT_FOUND,
452     wxT("invalid page index in wxBookCtrlBase::DoSetSelection()") );
453    
454     const int oldSel = GetSelection();
455    
456     if ( n != (size_t)oldSel )
457     {
458     wxBookCtrlBaseEvent *event = CreatePageChangingEvent();
459     bool allowed = false;
460    
461     if ( flags & SetSelection_SendEvent )
462     {
463     event->SetSelection(n);
464     event->SetOldSelection(oldSel);
465     event->SetEventObject(this);
466    
467     allowed = !GetEventHandler()->ProcessEvent(*event) || event->IsAllowed();
468     }
469    
470     if ( !(flags & SetSelection_SendEvent) || allowed)
471     {
472     if ( oldSel != wxNOT_FOUND )
473     m_pages[oldSel]->Hide();
474    
475     wxWindow *page = m_pages[n];
476     page->SetSize(GetPageRect());
477     page->Show();
478    
479     // change selection now to ignore the selection change event
480     UpdateSelectedPage(n);
481    
482     if ( flags & SetSelection_SendEvent )
483     {
484     // program allows the page change
485     MakeChangedEvent(*event);
486     (void)GetEventHandler()->ProcessEvent(*event);
487     }
488     }
489    
490     delete event;
491     }
492    
493     return oldSel;
494     }
495    
496    
497     #endif // wxUSE_BOOKCTRL

  ViewVC Help
Powered by ViewVC 1.1.22