]> git.saurik.com Git - wxWidgets.git/blame - src/generic/listbkg.cpp
fixed GetItemSpacing() inconsistency by deprecating the old function and adding a...
[wxWidgets.git] / src / generic / listbkg.cpp
CommitLineData
e9c0df38
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: generic/listbkg.cpp
3// Purpose: generic implementation of wxListbook
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 19.08.03
7// RCS-ID: $Id$
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#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "listbook.h"
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
28 #pragma hdrstop
29#endif
30
31#if wxUSE_LISTBOOK
32
33#include "wx/listctrl.h"
34#include "wx/statline.h"
35#include "wx/listbook.h"
5b24f0d3 36#include "wx/imaglist.h"
c59da60a 37#include "wx/settings.h"
e9c0df38
VZ
38
39// ----------------------------------------------------------------------------
40// constants
41// ----------------------------------------------------------------------------
42
43// margin between the list and the page, should be bigger than wxStaticLine
44// size
45const wxCoord MARGIN = 5;
46
47// ----------------------------------------------------------------------------
48// various wxWindows macros
49// ----------------------------------------------------------------------------
50
51IMPLEMENT_DYNAMIC_CLASS(wxListbook, wxControl)
52IMPLEMENT_DYNAMIC_CLASS(wxListbookEvent, wxNotifyEvent)
53
54const wxEventType wxEVT_COMMAND_LISTBOOK_PAGE_CHANGING = wxNewEventType();
55const wxEventType wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED = wxNewEventType();
f29395d0 56const int wxID_LISTBOOKLISTVIEW = wxNewId();
e9c0df38
VZ
57
58BEGIN_EVENT_TABLE(wxListbook, wxBookCtrl)
59 EVT_SIZE(wxListbook::OnSize)
60
f29395d0 61 EVT_LIST_ITEM_SELECTED(wxID_LISTBOOKLISTVIEW, wxListbook::OnListSelected)
e9c0df38
VZ
62END_EVENT_TABLE()
63
64// ============================================================================
65// wxListbook implementation
66// ============================================================================
67
68// ----------------------------------------------------------------------------
69// wxListbook creation
70// ----------------------------------------------------------------------------
71
72void wxListbook::Init()
73{
74 m_list = NULL;
75 m_line = NULL;
76 m_selection = wxNOT_FOUND;
77}
78
79bool
80wxListbook::Create(wxWindow *parent,
81 wxWindowID id,
82 const wxPoint& pos,
83 const wxSize& size,
84 long style,
85 const wxString& name)
86{
87 if ( (style & wxLB_ALIGN_MASK) == wxLB_DEFAULT )
88 {
89#ifdef __WXMAC__
90 style |= wxLB_TOP;
91#else // !__WXMAC__
92 style |= wxLB_LEFT;
93#endif // __WXMAC__/!__WXMAC__
94 }
95
96 if ( !wxControl::Create(parent, id, pos, size, style,
97 wxDefaultValidator, name) )
98 return false;
99
100 m_list = new wxListView
101 (
102 this,
f29395d0 103 wxID_LISTBOOKLISTVIEW,
e9c0df38
VZ
104 wxDefaultPosition,
105 wxDefaultSize,
4a06b348
VZ
106 wxBORDER_NONE | wxLC_ICON | wxLC_SINGLE_SEL |
107 (IsVertical() ? wxLC_ALIGN_LEFT : wxLC_ALIGN_TOP)
e9c0df38
VZ
108 );
109
110 m_line = new wxStaticLine
111 (
112 this,
113 -1,
114 wxDefaultPosition,
115 wxDefaultSize,
116 IsVertical() ? wxLI_HORIZONTAL : wxLI_VERTICAL
117 );
118
119 return true;
120}
121
122// ----------------------------------------------------------------------------
123// wxListbook geometry management
124// ----------------------------------------------------------------------------
125
126wxSize wxListbook::GetListSize() const
127{
4a06b348
VZ
128 const wxSize sizeClient = GetClientSize(),
129 sizeList = m_list->GetViewRect().GetSize();
e9c0df38
VZ
130
131 wxSize size;
132 if ( IsVertical() )
133 {
134 size.x = sizeClient.x;
4a06b348 135 size.y = sizeList.y;
e9c0df38
VZ
136 }
137 else // left/right aligned
138 {
4a06b348 139 size.x = sizeList.x;
e9c0df38
VZ
140 size.y = sizeClient.y;
141 }
142
143 return size;
144}
145
146wxRect wxListbook::GetPageRect() const
147{
148 const wxSize sizeList = GetListSize();
149
150 wxRect rectPage(wxPoint(0, 0), GetClientSize());
151 switch ( GetWindowStyle() & wxLB_ALIGN_MASK )
152 {
153 default:
154 wxFAIL_MSG( _T("unexpected wxListbook alignment") );
155 // fall through
156
157 case wxLB_TOP:
158 rectPage.y = sizeList.y + MARGIN;
159 // fall through
160
161 case wxLB_BOTTOM:
162 rectPage.height -= sizeList.y + MARGIN;
163 break;
164
165 case wxLB_LEFT:
166 rectPage.x = sizeList.x + MARGIN;
167 // fall through
168
169 case wxLB_RIGHT:
170 rectPage.width -= sizeList.x + MARGIN;
171 break;
172 }
173
174 return rectPage;
175}
176
177void wxListbook::OnSize(wxSizeEvent& event)
178{
f1160963
VZ
179 event.Skip();
180
181 if ( !m_list )
182 {
183 // we're not fully created yet
184 return;
185 }
186
e9c0df38
VZ
187 // resize the list control and the page area to fit inside our new size
188 const wxSize sizeClient = GetClientSize(),
189 sizeList = GetListSize();
190
191 wxPoint posList;
192 switch ( GetWindowStyle() & wxLB_ALIGN_MASK )
193 {
194 default:
195 wxFAIL_MSG( _T("unexpected wxListbook alignment") );
196 // fall through
197
198 case wxLB_TOP:
199 case wxLB_LEFT:
200 // posList is already ok
201 break;
202
203 case wxLB_BOTTOM:
204 posList.y = sizeClient.y - sizeList.y;
205 break;
206
207 case wxLB_RIGHT:
208 posList.x = sizeClient.x - sizeList.x;
209 break;
210 }
211
212 m_list->SetSize(posList.x, posList.y, sizeList.x, sizeList.y);
213
214 if ( m_line )
215 {
216 wxRect rectLine(wxPoint(0, 0), sizeClient);
217
218 switch ( GetWindowStyle() & wxLB_ALIGN_MASK )
219 {
220 case wxLB_TOP:
221 rectLine.y = sizeList.y + 1;
222 rectLine.height = MARGIN - 2;
223 break;
224
225 case wxLB_BOTTOM:
226 rectLine.height = MARGIN - 2;
227 rectLine.y = sizeClient.y - sizeList.y - rectLine.height;
228 break;
229
230 case wxLB_LEFT:
231 rectLine.x = sizeList.x + 1;
232 rectLine.width = MARGIN - 2;
233 break;
234
235 case wxLB_RIGHT:
236 rectLine.width = MARGIN - 2;
237 rectLine.x = sizeClient.x - sizeList.x - rectLine.width;
238 break;
239 }
240
241 m_line->SetSize(rectLine);
242 }
243
244 // we should always have some selection if possible
245 if ( m_selection == wxNOT_FOUND && GetPageCount() )
246 {
247 SetSelection(0);
248 }
249
250 if ( m_selection != wxNOT_FOUND )
251 {
252 wxWindow *page = m_pages[m_selection];
253 wxCHECK_RET( page, _T("NULL page in wxListbook?") );
254
255 page->SetSize(GetPageRect());
256 if ( !page->IsShown() )
257 {
258 page->Show();
259 }
260 }
e9c0df38
VZ
261}
262
263wxSize wxListbook::CalcSizeFromPage(const wxSize& sizePage) const
264{
265 // we need to add the size of the list control and the margin
266 const wxSize sizeList = GetListSize();
267
268 wxSize size = sizePage;
269 if ( IsVertical() )
270 {
271 size.y += sizeList.y + MARGIN;
272 }
273 else // left/right aligned
274 {
275 size.x += sizeList.x + MARGIN;
276 }
277
278 return size;
279}
280
281
282// ----------------------------------------------------------------------------
283// accessing the pages
284// ----------------------------------------------------------------------------
285
286bool wxListbook::SetPageText(size_t n, const wxString& strText)
287{
288 m_list->SetItemText(n, strText);
289
290 return true;
291}
292
293wxString wxListbook::GetPageText(size_t n) const
294{
295 return m_list->GetItemText(n);
296}
297
298int wxListbook::GetPageImage(size_t WXUNUSED(n)) const
299{
300 wxFAIL_MSG( _T("wxListbook::GetPageImage() not implemented") );
301
302 return -1;
303}
304
305bool wxListbook::SetPageImage(size_t n, int imageId)
306{
307 return m_list->SetItemImage(n, imageId, imageId);
308}
309
310// ----------------------------------------------------------------------------
311// image list stuff
312// ----------------------------------------------------------------------------
313
314void wxListbook::SetImageList(wxImageList *imageList)
315{
316 m_list->SetImageList(imageList, wxIMAGE_LIST_NORMAL);
317
318 wxBookCtrl::SetImageList(imageList);
319}
320
321// ----------------------------------------------------------------------------
322// selection
323// ----------------------------------------------------------------------------
324
325int wxListbook::GetSelection() const
326{
327 return m_selection;
328}
329
330int wxListbook::SetSelection(size_t n)
331{
332 wxCHECK_MSG( n < GetPageCount(), wxNOT_FOUND,
333 _T("invalid page index in wxListbook::SetSelection()") );
334
335 int selOld = m_selection;
336
337 if ( (int)n != m_selection )
338 {
339 m_selection = n;
340
341 m_list->Select(m_selection);
342 m_list->Focus(m_selection);
343 }
344
345 return selOld;
346}
347
348
349// ----------------------------------------------------------------------------
350// adding/removing the pages
351// ----------------------------------------------------------------------------
352
353bool
354wxListbook::InsertPage(size_t n,
355 wxWindow *page,
356 const wxString& text,
357 bool bSelect,
358 int imageId)
359{
360 if ( !wxBookCtrl::InsertPage(n, page, text, bSelect, imageId) )
361 return false;
362
363 m_list->InsertItem(n, text, imageId);
364
365 if ( bSelect )
366 {
367 m_list->Select(n);
368 m_list->Focus(n);
369 }
370 else // don't select this page
371 {
372 // it will be shown only when selected
373 page->Hide();
374 }
375
376 return true;
377}
378
379wxWindow *wxListbook::DoRemovePage(size_t page)
380{
381 wxWindow *win = wxBookCtrl::DoRemovePage(page);
382 if ( win )
383 {
384 m_list->DeleteItem(page);
385 }
386
387 return win;
388}
389
390// ----------------------------------------------------------------------------
391// wxListbook events
392// ----------------------------------------------------------------------------
393
394void wxListbook::OnListSelected(wxListEvent& eventList)
395{
396 const int selNew = eventList.GetIndex();
397
398 if ( selNew == m_selection )
399 {
400 // this event can only come from our own Select(m_selection) below
401 // which we call when the page change is vetoed, so we should simply
402 // ignore it
403 return;
404 }
405
406 // first send "change in progress" event which may be vetoed by user
407 wxListbookEvent eventIng(wxEVT_COMMAND_LISTBOOK_PAGE_CHANGING, GetId());
408
409 eventIng.SetEventObject(this);
410 eventIng.SetSelection(selNew);
411 eventIng.SetOldSelection(m_selection);
412 if ( GetEventHandler()->ProcessEvent(eventIng) && !eventIng.IsAllowed() )
413 {
414 m_list->Select(m_selection);
415 return;
416 }
417
418 // change allowed: do change the page and notify the user about it
419 if ( m_selection != wxNOT_FOUND )
420 m_pages[m_selection]->Hide();
421 wxWindow *page = m_pages[m_selection = selNew];
422 page->SetSize(GetPageRect());
423 page->Show();
424
425 wxListbookEvent eventEd(wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED, GetId());
426
427 eventEd.SetEventObject(this);
428 eventEd.SetSelection(selNew);
429 eventEd.SetOldSelection(m_selection);
430
431 (void)GetEventHandler()->ProcessEvent(eventEd);
432}
433
434#endif // wxUSE_LISTBOOK
435