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"
36 #include "wx/imaglist.h"
38 // ----------------------------------------------------------------------------
40 // ----------------------------------------------------------------------------
42 // margin between the list and the page, should be bigger than wxStaticLine
44 const wxCoord MARGIN
= 5;
46 // ----------------------------------------------------------------------------
47 // various wxWindows macros
48 // ----------------------------------------------------------------------------
50 IMPLEMENT_DYNAMIC_CLASS(wxListbook
, wxControl
)
51 IMPLEMENT_DYNAMIC_CLASS(wxListbookEvent
, wxNotifyEvent
)
53 const wxEventType wxEVT_COMMAND_LISTBOOK_PAGE_CHANGING
= wxNewEventType();
54 const wxEventType wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED
= wxNewEventType();
56 BEGIN_EVENT_TABLE(wxListbook
, wxBookCtrl
)
57 EVT_SIZE(wxListbook::OnSize
)
59 EVT_LIST_ITEM_SELECTED(wxID_ANY
, wxListbook::OnListSelected
)
62 // ============================================================================
63 // wxListbook implementation
64 // ============================================================================
66 // ----------------------------------------------------------------------------
67 // wxListbook creation
68 // ----------------------------------------------------------------------------
70 void wxListbook::Init()
74 m_selection
= wxNOT_FOUND
;
78 wxListbook::Create(wxWindow
*parent
,
85 if ( (style
& wxLB_ALIGN_MASK
) == wxLB_DEFAULT
)
91 #endif // __WXMAC__/!__WXMAC__
94 if ( !wxControl::Create(parent
, id
, pos
, size
, style
,
95 wxDefaultValidator
, name
) )
98 m_list
= new wxListView
104 wxLC_ICON
| wxLC_SINGLE_SEL
107 m_line
= new wxStaticLine
113 IsVertical() ? wxLI_HORIZONTAL
: wxLI_VERTICAL
119 // ----------------------------------------------------------------------------
120 // wxListbook geometry management
121 // ----------------------------------------------------------------------------
123 wxSize
wxListbook::GetListSize() const
125 const wxSize sizeClient
= GetClientSize();
127 // we need to find the longest/tallest label
128 wxCoord widthMax
= 0,
130 const int count
= m_list
->GetItemCount();
133 for ( int i
= 0; i
< count
; i
++ )
136 m_list
->GetItemRect(i
, r
);
138 wxCoord w
= r
.x
+ r
.width
,
151 size
.x
= sizeClient
.x
;
154 else // left/right aligned
156 size
.x
= widthMax
+ 10;
157 size
.y
= sizeClient
.y
;
163 wxRect
wxListbook::GetPageRect() const
165 const wxSize sizeList
= GetListSize();
167 wxRect
rectPage(wxPoint(0, 0), GetClientSize());
168 switch ( GetWindowStyle() & wxLB_ALIGN_MASK
)
171 wxFAIL_MSG( _T("unexpected wxListbook alignment") );
175 rectPage
.y
= sizeList
.y
+ MARGIN
;
179 rectPage
.height
-= sizeList
.y
+ MARGIN
;
183 rectPage
.x
= sizeList
.x
+ MARGIN
;
187 rectPage
.width
-= sizeList
.x
+ MARGIN
;
194 void wxListbook::OnSize(wxSizeEvent
& event
)
200 // we're not fully created yet
204 // resize the list control and the page area to fit inside our new size
205 const wxSize sizeClient
= GetClientSize(),
206 sizeList
= GetListSize();
209 switch ( GetWindowStyle() & wxLB_ALIGN_MASK
)
212 wxFAIL_MSG( _T("unexpected wxListbook alignment") );
217 // posList is already ok
221 posList
.y
= sizeClient
.y
- sizeList
.y
;
225 posList
.x
= sizeClient
.x
- sizeList
.x
;
229 m_list
->SetSize(posList
.x
, posList
.y
, sizeList
.x
, sizeList
.y
);
233 wxRect
rectLine(wxPoint(0, 0), sizeClient
);
235 switch ( GetWindowStyle() & wxLB_ALIGN_MASK
)
238 rectLine
.y
= sizeList
.y
+ 1;
239 rectLine
.height
= MARGIN
- 2;
243 rectLine
.height
= MARGIN
- 2;
244 rectLine
.y
= sizeClient
.y
- sizeList
.y
- rectLine
.height
;
248 rectLine
.x
= sizeList
.x
+ 1;
249 rectLine
.width
= MARGIN
- 2;
253 rectLine
.width
= MARGIN
- 2;
254 rectLine
.x
= sizeClient
.x
- sizeList
.x
- rectLine
.width
;
258 m_line
->SetSize(rectLine
);
261 // we should always have some selection if possible
262 if ( m_selection
== wxNOT_FOUND
&& GetPageCount() )
267 if ( m_selection
!= wxNOT_FOUND
)
269 wxWindow
*page
= m_pages
[m_selection
];
270 wxCHECK_RET( page
, _T("NULL page in wxListbook?") );
272 page
->SetSize(GetPageRect());
273 if ( !page
->IsShown() )
280 wxSize
wxListbook::CalcSizeFromPage(const wxSize
& sizePage
) const
282 // we need to add the size of the list control and the margin
283 const wxSize sizeList
= GetListSize();
285 wxSize size
= sizePage
;
288 size
.y
+= sizeList
.y
+ MARGIN
;
290 else // left/right aligned
292 size
.x
+= sizeList
.x
+ MARGIN
;
299 // ----------------------------------------------------------------------------
300 // accessing the pages
301 // ----------------------------------------------------------------------------
303 bool wxListbook::SetPageText(size_t n
, const wxString
& strText
)
305 m_list
->SetItemText(n
, strText
);
310 wxString
wxListbook::GetPageText(size_t n
) const
312 return m_list
->GetItemText(n
);
315 int wxListbook::GetPageImage(size_t WXUNUSED(n
)) const
317 wxFAIL_MSG( _T("wxListbook::GetPageImage() not implemented") );
322 bool wxListbook::SetPageImage(size_t n
, int imageId
)
324 return m_list
->SetItemImage(n
, imageId
, imageId
);
327 // ----------------------------------------------------------------------------
329 // ----------------------------------------------------------------------------
331 void wxListbook::SetImageList(wxImageList
*imageList
)
333 m_list
->SetImageList(imageList
, wxIMAGE_LIST_NORMAL
);
335 wxBookCtrl::SetImageList(imageList
);
338 // ----------------------------------------------------------------------------
340 // ----------------------------------------------------------------------------
342 int wxListbook::GetSelection() const
347 int wxListbook::SetSelection(size_t n
)
349 wxCHECK_MSG( n
< GetPageCount(), wxNOT_FOUND
,
350 _T("invalid page index in wxListbook::SetSelection()") );
352 int selOld
= m_selection
;
354 if ( (int)n
!= m_selection
)
358 m_list
->Select(m_selection
);
359 m_list
->Focus(m_selection
);
366 // ----------------------------------------------------------------------------
367 // adding/removing the pages
368 // ----------------------------------------------------------------------------
371 wxListbook::InsertPage(size_t n
,
373 const wxString
& text
,
377 if ( !wxBookCtrl::InsertPage(n
, page
, text
, bSelect
, imageId
) )
380 m_list
->InsertItem(n
, text
, imageId
);
387 else // don't select this page
389 // it will be shown only when selected
396 wxWindow
*wxListbook::DoRemovePage(size_t page
)
398 wxWindow
*win
= wxBookCtrl::DoRemovePage(page
);
401 m_list
->DeleteItem(page
);
407 // ----------------------------------------------------------------------------
409 // ----------------------------------------------------------------------------
411 void wxListbook::OnListSelected(wxListEvent
& eventList
)
413 const int selNew
= eventList
.GetIndex();
415 if ( selNew
== m_selection
)
417 // this event can only come from our own Select(m_selection) below
418 // which we call when the page change is vetoed, so we should simply
423 // first send "change in progress" event which may be vetoed by user
424 wxListbookEvent
eventIng(wxEVT_COMMAND_LISTBOOK_PAGE_CHANGING
, GetId());
426 eventIng
.SetEventObject(this);
427 eventIng
.SetSelection(selNew
);
428 eventIng
.SetOldSelection(m_selection
);
429 if ( GetEventHandler()->ProcessEvent(eventIng
) && !eventIng
.IsAllowed() )
431 m_list
->Select(m_selection
);
435 // change allowed: do change the page and notify the user about it
436 if ( m_selection
!= wxNOT_FOUND
)
437 m_pages
[m_selection
]->Hide();
438 wxWindow
*page
= m_pages
[m_selection
= selNew
];
439 page
->SetSize(GetPageRect());
442 wxListbookEvent
eventEd(wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED
, GetId());
444 eventEd
.SetEventObject(this);
445 eventEd
.SetSelection(selNew
);
446 eventEd
.SetOldSelection(m_selection
);
448 (void)GetEventHandler()->ProcessEvent(eventEd
);
451 #endif // wxUSE_LISTBOOK