]>
git.saurik.com Git - wxWidgets.git/blob - src/common/bookctrl.cpp
da06cdafeba1ce300f7bc3f26a1ccdde4ffda51b
   1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/common/bookctrl.cpp 
   3 // Purpose:     wxBookCtrlBase implementation 
   4 // Author:      Vadim Zeitlin 
   8 // Copyright:   (c) 2003 Vadim Zeitlin <vadim@wxwindows.org> 
   9 // Licence:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  29 #include "wx/imaglist.h" 
  31 #include "wx/bookctrl.h" 
  33 // ============================================================================ 
  35 // ============================================================================ 
  37 // ---------------------------------------------------------------------------- 
  39 // ---------------------------------------------------------------------------- 
  41 IMPLEMENT_ABSTRACT_CLASS(wxBookCtrlBase
, wxControl
) 
  43 BEGIN_EVENT_TABLE(wxBookCtrlBase
, wxControl
) 
  44     EVT_SIZE(wxBookCtrlBase::OnSize
) 
  46     EVT_HELP(wxID_ANY
, wxBookCtrlBase::OnHelp
) 
  50 // ---------------------------------------------------------------------------- 
  51 // constructors and destructors 
  52 // ---------------------------------------------------------------------------- 
  54 void wxBookCtrlBase::Init() 
  58     m_ownsImageList 
= false; 
  59     m_fitToCurrentPage 
= false; 
  61 #if defined(__WXWINCE__) 
  68     m_controlSizer 
= NULL
; 
  72 wxBookCtrlBase::Create(wxWindow 
*parent
, 
  79     return wxControl::Create
 
  91 wxBookCtrlBase::~wxBookCtrlBase() 
  93     if ( m_ownsImageList 
) 
 100 // ---------------------------------------------------------------------------- 
 102 // ---------------------------------------------------------------------------- 
 104 void wxBookCtrlBase::SetImageList(wxImageList 
*imageList
) 
 106     if ( m_ownsImageList 
) 
 111         m_ownsImageList 
= false; 
 114     m_imageList 
= imageList
; 
 117 void wxBookCtrlBase::AssignImageList(wxImageList
* imageList
) 
 119     SetImageList(imageList
); 
 121     m_ownsImageList 
= true; 
 124 // ---------------------------------------------------------------------------- 
 126 // ---------------------------------------------------------------------------- 
 128 void wxBookCtrlBase::DoInvalidateBestSize() 
 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 
 135         m_bookctrl
->InvalidateBestSize(); 
 137         wxControl::InvalidateBestSize(); 
 140 void wxBookCtrlBase::SetPageSize(const wxSize
& size
) 
 142     SetClientSize(CalcSizeFromPage(size
)); 
 145 wxSize 
wxBookCtrlBase::DoGetBestSize() const 
 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
++ ) 
 153         const wxWindow 
* const pPage 
= m_pages
[nPage
]; 
 156             wxSize 
childBestSize(pPage
->GetBestSize()); 
 158             if ( childBestSize
.x 
> bestSize
.x 
) 
 159                 bestSize
.x 
= childBestSize
.x
; 
 161             if ( childBestSize
.y 
> bestSize
.y 
) 
 162                 bestSize
.y 
= childBestSize
.y
; 
 166     if (m_fitToCurrentPage 
&& GetCurrentPage()) 
 167         bestSize 
= GetCurrentPage()->GetBestSize(); 
 169     // convert display area to window area, adding the size necessary for the 
 171     wxSize best 
= CalcSizeFromPage(bestSize
); 
 176 wxRect 
wxBookCtrlBase::GetPageRect() const 
 178     const wxSize size 
= GetControllerSize(); 
 181     wxRect 
rectPage(pt
, GetClientSize()); 
 183     switch ( GetWindowStyle() & wxBK_ALIGN_MASK 
) 
 186             wxFAIL_MSG( wxT("unexpected alignment") ); 
 190             rectPage
.y 
= size
.y 
+ GetInternalBorder(); 
 194             rectPage
.height 
-= size
.y 
+ GetInternalBorder(); 
 195             if (rectPage
.height 
< 0) 
 200             rectPage
.x 
= size
.x 
+ GetInternalBorder(); 
 204             rectPage
.width 
-= size
.x 
+ GetInternalBorder(); 
 205             if (rectPage
.width 
< 0) 
 214 void wxBookCtrlBase::DoSize() 
 218         // we're not fully created yet or OnSize() should be hidden by derived class 
 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() ); 
 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 
) 
 236             wxSize sizeBorder2 
= m_bookctrl
->GetSize() - m_bookctrl
->GetClientSize(); 
 237             m_bookctrl
->SetClientSize( sizeCtrl2
.x 
- sizeBorder2
.x
, sizeCtrl2
.y 
- sizeBorder2
.y 
); 
 240         const wxSize sizeNew 
= m_bookctrl
->GetSize(); 
 242         switch ( GetWindowStyle() & wxBK_ALIGN_MASK 
) 
 245                 wxFAIL_MSG( wxT("unexpected alignment") ); 
 250                 // posCtrl is already ok 
 254                 posCtrl
.y 
= sizeClient
.y 
- sizeNew
.y
; 
 258                 posCtrl
.x 
= sizeClient
.x 
- sizeNew
.x
; 
 262         if ( m_bookctrl
->GetPosition() != posCtrl 
) 
 263             m_bookctrl
->Move(posCtrl
); 
 266     // resize all pages to fit the new control size 
 267     const wxRect pageRect 
= GetPageRect(); 
 268     const unsigned pagesCount 
= m_pages
.GetCount(); 
 269     for ( unsigned int i 
= 0; i 
< pagesCount
; ++i 
) 
 271         wxWindow 
* const page 
= m_pages
[i
]; 
 274             wxASSERT_MSG( AllowNullPage(), 
 275                 wxT("Null page in a control that does not allow null pages?") ); 
 279         page
->SetSize(pageRect
); 
 283 void wxBookCtrlBase::OnSize(wxSizeEvent
& event
) 
 290 wxSize 
wxBookCtrlBase::GetControllerSize() const 
 295     const wxSize sizeClient 
= GetClientSize(), 
 296                  sizeCtrl 
= m_bookctrl
->GetBestSize(); 
 302         size
.x 
= sizeClient
.x
; 
 305     else // left/right aligned 
 308         size
.y 
= sizeClient
.y
; 
 314 // ---------------------------------------------------------------------------- 
 315 // miscellaneous stuff 
 316 // ---------------------------------------------------------------------------- 
 320 void wxBookCtrlBase::OnHelp(wxHelpEvent
& event
) 
 322     // determine where does this even originate from to avoid redirecting it 
 323     // back to the page which generated it (resulting in an infinite loop) 
 325     // notice that we have to check in the hard(er) way instead of just testing 
 326     // if the event object == this because the book control can have other 
 327     // subcontrols inside it (e.g. wxSpinButton in case of a notebook in wxUniv) 
 328     wxWindow 
*source 
= wxStaticCast(event
.GetEventObject(), wxWindow
); 
 329     while ( source 
&& source 
!= this && source
->GetParent() != this ) 
 331         source 
= source
->GetParent(); 
 334     if ( source 
&& m_pages
.Index(source
) == wxNOT_FOUND 
) 
 336         // this event is for the book control itself, redirect it to the 
 337         // corresponding page 
 338         wxWindow 
*page 
= NULL
; 
 340         if ( event
.GetOrigin() == wxHelpEvent::Origin_HelpButton 
) 
 342             // show help for the page under the mouse 
 343             const int pagePos 
= HitTest(ScreenToClient(event
.GetPosition())); 
 345             if ( pagePos 
!= wxNOT_FOUND
) 
 347                 page 
= GetPage((size_t)pagePos
); 
 350         else // event from keyboard or unknown source 
 352             // otherwise show the current page help 
 353             page 
= GetCurrentPage(); 
 358             // change event object to the page to avoid infinite recursion if 
 359             // we get this event ourselves if the page doesn't handle it 
 360             event
.SetEventObject(page
); 
 362             if ( page
->GetEventHandler()->ProcessEvent(event
) ) 
 364                 // don't call event.Skip() 
 369     //else: event coming from one of our pages already 
 376 // ---------------------------------------------------------------------------- 
 378 // ---------------------------------------------------------------------------- 
 381 wxBookCtrlBase::InsertPage(size_t nPage
, 
 383                            const wxString
& WXUNUSED(text
), 
 384                            bool WXUNUSED(bSelect
), 
 385                            int WXUNUSED(imageId
)) 
 387     wxCHECK_MSG( page 
|| AllowNullPage(), false, 
 388                  wxT("NULL page in wxBookCtrlBase::InsertPage()") ); 
 389     wxCHECK_MSG( nPage 
<= m_pages
.size(), false, 
 390                  wxT("invalid page index in wxBookCtrlBase::InsertPage()") ); 
 392     m_pages
.Insert(page
, nPage
); 
 394         page
->SetSize(GetPageRect()); 
 396     DoInvalidateBestSize(); 
 401 bool wxBookCtrlBase::DeletePage(size_t nPage
) 
 403     wxWindow 
*page 
= DoRemovePage(nPage
); 
 404     if ( !(page 
|| AllowNullPage()) ) 
 407     // delete NULL is harmless 
 413 wxWindow 
*wxBookCtrlBase::DoRemovePage(size_t nPage
) 
 415     wxCHECK_MSG( nPage 
< m_pages
.size(), NULL
, 
 416                  wxT("invalid page index in wxBookCtrlBase::DoRemovePage()") ); 
 418     wxWindow 
*pageRemoved 
= m_pages
[nPage
]; 
 419     m_pages
.RemoveAt(nPage
); 
 420     DoInvalidateBestSize(); 
 425 int wxBookCtrlBase::GetNextPage(bool forward
) const 
 429     int nMax 
= GetPageCount(); 
 430     if ( nMax
-- ) // decrement it to get the last valid index 
 432         int nSel 
= GetSelection(); 
 434         // change selection wrapping if it becomes invalid 
 435         nPage 
= forward 
? nSel 
== nMax 
? 0 
 440     else // notebook is empty, no next page 
 448 int wxBookCtrlBase::DoSetSelection(size_t n
, int flags
) 
 450     wxCHECK_MSG( n 
< GetPageCount(), wxNOT_FOUND
, 
 451                  wxT("invalid page index in wxBookCtrlBase::DoSetSelection()") ); 
 453     const int oldSel 
= GetSelection(); 
 455     if ( n 
!= (size_t)oldSel 
) 
 457         wxBookCtrlEvent 
*event 
= CreatePageChangingEvent(); 
 458         bool allowed 
= false; 
 460         if ( flags 
& SetSelection_SendEvent 
) 
 462             event
->SetSelection(n
); 
 463             event
->SetOldSelection(oldSel
); 
 464             event
->SetEventObject(this); 
 466             allowed 
= !GetEventHandler()->ProcessEvent(*event
) || event
->IsAllowed(); 
 469         if ( !(flags 
& SetSelection_SendEvent
) || allowed
) 
 471             if ( oldSel 
!= wxNOT_FOUND 
) 
 472                 m_pages
[oldSel
]->Hide(); 
 474             wxWindow 
*page 
= m_pages
[n
]; 
 475             page
->SetSize(GetPageRect()); 
 478             // change selection now to ignore the selection change event 
 479             UpdateSelectedPage(n
); 
 481             if ( flags 
& SetSelection_SendEvent 
) 
 483                 // program allows the page change 
 484                 MakeChangedEvent(*event
); 
 485                 (void)GetEventHandler()->ProcessEvent(*event
); 
 495 IMPLEMENT_DYNAMIC_CLASS(wxBookCtrlEvent
, wxNotifyEvent
) 
 497 #endif // wxUSE_BOOKCTRL