1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        generic/listbkg.cpp 
   3 // Purpose:     generic implementation of wxListbook 
   4 // Author:      Vadim Zeitlin 
   8 // Copyright:   (c) 2003 Vadim Zeitlin <vadim@wxwindows.org> 
   9 // Licence:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  21     #pragma implementation "listbook.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  33 #include "wx/listctrl.h" 
  34 #include "wx/statline.h" 
  35 #include "wx/listbook.h" 
  37 // ---------------------------------------------------------------------------- 
  39 // ---------------------------------------------------------------------------- 
  41 // margin between the list and the page, should be bigger than wxStaticLine 
  43 const wxCoord MARGIN 
= 5; 
  45 // ---------------------------------------------------------------------------- 
  46 // various wxWindows macros 
  47 // ---------------------------------------------------------------------------- 
  49 IMPLEMENT_DYNAMIC_CLASS(wxListbook
, wxControl
) 
  50 IMPLEMENT_DYNAMIC_CLASS(wxListbookEvent
, wxNotifyEvent
) 
  52 const wxEventType wxEVT_COMMAND_LISTBOOK_PAGE_CHANGING 
= wxNewEventType(); 
  53 const wxEventType wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED 
= wxNewEventType(); 
  55 BEGIN_EVENT_TABLE(wxListbook
, wxBookCtrl
) 
  56     EVT_SIZE(wxListbook::OnSize
) 
  58     EVT_LIST_ITEM_SELECTED(wxID_ANY
, wxListbook::OnListSelected
) 
  61 // ============================================================================ 
  62 // wxListbook implementation 
  63 // ============================================================================ 
  65 // ---------------------------------------------------------------------------- 
  66 // wxListbook creation 
  67 // ---------------------------------------------------------------------------- 
  69 void wxListbook::Init() 
  73     m_selection 
= wxNOT_FOUND
; 
  77 wxListbook::Create(wxWindow 
*parent
, 
  84     if ( (style 
& wxLB_ALIGN_MASK
) == wxLB_DEFAULT 
) 
  90 #endif // __WXMAC__/!__WXMAC__ 
  93     if ( !wxControl::Create(parent
, id
, pos
, size
, style
, 
  94                             wxDefaultValidator
, name
) ) 
  97     m_list 
= new wxListView
 
 103                     wxLC_ICON 
| wxLC_SINGLE_SEL
 
 106     m_line 
= new wxStaticLine
 
 112                     IsVertical() ? wxLI_HORIZONTAL 
: wxLI_VERTICAL
 
 118 // ---------------------------------------------------------------------------- 
 119 // wxListbook geometry management 
 120 // ---------------------------------------------------------------------------- 
 122 wxSize 
wxListbook::GetListSize() const 
 124     const wxSize sizeClient 
= GetClientSize(); 
 126     // we need to find the longest/tallest label 
 127     wxCoord widthMax 
= 0, 
 129     const int count 
= m_list
->GetItemCount(); 
 132         for ( int i 
= 0; i 
< count
; i
++ ) 
 135             m_list
->GetItemRect(i
, r
); 
 137             wxCoord w 
= r
.x 
+ r
.width
, 
 150         size
.x 
= sizeClient
.x
; 
 153     else // left/right aligned 
 155         size
.x 
= widthMax 
+ 10; 
 156         size
.y 
= sizeClient
.y
; 
 162 wxRect 
wxListbook::GetPageRect() const 
 164     const wxSize sizeList 
= GetListSize(); 
 166     wxRect 
rectPage(wxPoint(0, 0), GetClientSize()); 
 167     switch ( GetWindowStyle() & wxLB_ALIGN_MASK 
) 
 170             wxFAIL_MSG( _T("unexpected wxListbook alignment") ); 
 174             rectPage
.y 
= sizeList
.y 
+ MARGIN
; 
 178             rectPage
.height 
-= sizeList
.y 
+ MARGIN
; 
 182             rectPage
.x 
= sizeList
.x 
+ MARGIN
; 
 186             rectPage
.width 
-= sizeList
.x 
+ MARGIN
; 
 193 void wxListbook::OnSize(wxSizeEvent
& event
) 
 195     // resize the list control and the page area to fit inside our new size 
 196     const wxSize sizeClient 
= GetClientSize(), 
 197                  sizeList 
= GetListSize(); 
 200     switch ( GetWindowStyle() & wxLB_ALIGN_MASK 
) 
 203             wxFAIL_MSG( _T("unexpected wxListbook alignment") ); 
 208             // posList is already ok 
 212             posList
.y 
= sizeClient
.y 
- sizeList
.y
; 
 216             posList
.x 
= sizeClient
.x 
- sizeList
.x
; 
 220     m_list
->SetSize(posList
.x
, posList
.y
, sizeList
.x
, sizeList
.y
); 
 224         wxRect 
rectLine(wxPoint(0, 0), sizeClient
); 
 226         switch ( GetWindowStyle() & wxLB_ALIGN_MASK 
) 
 229                 rectLine
.y 
= sizeList
.y 
+ 1; 
 230                 rectLine
.height 
= MARGIN 
- 2; 
 234                 rectLine
.height 
= MARGIN 
- 2; 
 235                 rectLine
.y 
= sizeClient
.y 
- sizeList
.y 
- rectLine
.height
; 
 239                 rectLine
.x 
= sizeList
.x 
+ 1; 
 240                 rectLine
.width 
= MARGIN 
- 2; 
 244                 rectLine
.width 
= MARGIN 
- 2; 
 245                 rectLine
.x 
= sizeClient
.x 
- sizeList
.x 
- rectLine
.width
; 
 249         m_line
->SetSize(rectLine
); 
 252     // we should always have some selection if possible 
 253     if ( m_selection 
== wxNOT_FOUND 
&& GetPageCount() ) 
 258     if ( m_selection 
!= wxNOT_FOUND 
) 
 260         wxWindow 
*page 
= m_pages
[m_selection
]; 
 261         wxCHECK_RET( page
, _T("NULL page in wxListbook?") ); 
 263         page
->SetSize(GetPageRect()); 
 264         if ( !page
->IsShown() ) 
 273 wxSize 
wxListbook::CalcSizeFromPage(const wxSize
& sizePage
) const 
 275     // we need to add the size of the list control and the margin 
 276     const wxSize sizeList 
= GetListSize(); 
 278     wxSize size 
= sizePage
; 
 281         size
.y 
+= sizeList
.y 
+ MARGIN
; 
 283     else // left/right aligned 
 285         size
.x 
+= sizeList
.x 
+ MARGIN
; 
 292 // ---------------------------------------------------------------------------- 
 293 // accessing the pages 
 294 // ---------------------------------------------------------------------------- 
 296 bool wxListbook::SetPageText(size_t n
, const wxString
& strText
) 
 298     m_list
->SetItemText(n
, strText
); 
 303 wxString 
wxListbook::GetPageText(size_t n
) const 
 305     return m_list
->GetItemText(n
); 
 308 int wxListbook::GetPageImage(size_t WXUNUSED(n
)) const 
 310     wxFAIL_MSG( _T("wxListbook::GetPageImage() not implemented") ); 
 315 bool wxListbook::SetPageImage(size_t n
, int imageId
) 
 317     return m_list
->SetItemImage(n
, imageId
, imageId
); 
 320 // ---------------------------------------------------------------------------- 
 322 // ---------------------------------------------------------------------------- 
 324 void wxListbook::SetImageList(wxImageList 
*imageList
) 
 326     m_list
->SetImageList(imageList
, wxIMAGE_LIST_NORMAL
); 
 328     wxBookCtrl::SetImageList(imageList
); 
 331 // ---------------------------------------------------------------------------- 
 333 // ---------------------------------------------------------------------------- 
 335 int wxListbook::GetSelection() const 
 340 int wxListbook::SetSelection(size_t n
) 
 342     wxCHECK_MSG( n 
< GetPageCount(), wxNOT_FOUND
, 
 343                  _T("invalid page index in wxListbook::SetSelection()") ); 
 345     int selOld 
= m_selection
; 
 347     if ( (int)n 
!= m_selection 
) 
 351         m_list
->Select(m_selection
); 
 352         m_list
->Focus(m_selection
); 
 359 // ---------------------------------------------------------------------------- 
 360 // adding/removing the pages 
 361 // ---------------------------------------------------------------------------- 
 364 wxListbook::InsertPage(size_t n
, 
 366                        const wxString
& text
, 
 370     if ( !wxBookCtrl::InsertPage(n
, page
, text
, bSelect
, imageId
) ) 
 373     m_list
->InsertItem(n
, text
, imageId
); 
 380     else // don't select this page 
 382         // it will be shown only when selected 
 389 wxWindow 
*wxListbook::DoRemovePage(size_t page
) 
 391     wxWindow 
*win 
= wxBookCtrl::DoRemovePage(page
); 
 394         m_list
->DeleteItem(page
); 
 400 // ---------------------------------------------------------------------------- 
 402 // ---------------------------------------------------------------------------- 
 404 void wxListbook::OnListSelected(wxListEvent
& eventList
) 
 406     const int selNew 
= eventList
.GetIndex(); 
 408     if ( selNew 
== m_selection 
) 
 410         // this event can only come from our own Select(m_selection) below 
 411         // which we call when the page change is vetoed, so we should simply 
 416     // first send "change in progress" event which may be vetoed by user 
 417     wxListbookEvent 
eventIng(wxEVT_COMMAND_LISTBOOK_PAGE_CHANGING
, GetId()); 
 419     eventIng
.SetEventObject(this); 
 420     eventIng
.SetSelection(selNew
); 
 421     eventIng
.SetOldSelection(m_selection
); 
 422     if ( GetEventHandler()->ProcessEvent(eventIng
) && !eventIng
.IsAllowed() ) 
 424         m_list
->Select(m_selection
); 
 428     // change allowed: do change the page and notify the user about it 
 429     if ( m_selection 
!= wxNOT_FOUND 
) 
 430         m_pages
[m_selection
]->Hide(); 
 431     wxWindow 
*page 
= m_pages
[m_selection 
= selNew
]; 
 432     page
->SetSize(GetPageRect()); 
 435     wxListbookEvent 
eventEd(wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED
, GetId()); 
 437     eventEd
.SetEventObject(this); 
 438     eventEd
.SetSelection(selNew
); 
 439     eventEd
.SetOldSelection(m_selection
); 
 441     (void)GetEventHandler()->ProcessEvent(eventEd
); 
 444 #endif // wxUSE_LISTBOOK