]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/generic/choicbkg.cpp
fix for a crash due to using NULL inputConv in Unicode build introduced in rev 1.162
[wxWidgets.git] / src / generic / choicbkg.cpp
... / ...
CommitLineData
1///////////////////////////////////////////////////////////////////////////////
2// Name: generic/choicbkg.cpp
3// Purpose: generic implementation of wxChoicebook
4// Author: Vadim Zeitlin
5// Modified by: Wlodzimierz ABX Skiba from generic/listbkg.cpp
6// Created: 15.09.04
7// RCS-ID: $Id$
8// Copyright: (c) Vadim Zeitlin, Wlodzimierz Skiba
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_CHOICEBOOK
28
29#include "wx/choice.h"
30#include "wx/choicebk.h"
31#include "wx/imaglist.h"
32#include "wx/settings.h"
33
34// ----------------------------------------------------------------------------
35// constants
36// ----------------------------------------------------------------------------
37
38// margin between the choice and the page
39#if defined(__WXWINCE__)
40const wxCoord MARGIN = 1;
41#else
42const wxCoord MARGIN = 5;
43#endif
44
45// ----------------------------------------------------------------------------
46// various wxWidgets macros
47// ----------------------------------------------------------------------------
48
49// check that the page index is valid
50#define IS_VALID_PAGE(nPage) ((nPage) < GetPageCount())
51
52// ----------------------------------------------------------------------------
53// event table
54// ----------------------------------------------------------------------------
55
56IMPLEMENT_DYNAMIC_CLASS(wxChoicebook, wxControl)
57IMPLEMENT_DYNAMIC_CLASS(wxChoicebookEvent, wxNotifyEvent)
58
59const wxEventType wxEVT_COMMAND_CHOICEBOOK_PAGE_CHANGING = wxNewEventType();
60const wxEventType wxEVT_COMMAND_CHOICEBOOK_PAGE_CHANGED = wxNewEventType();
61const int wxID_CHOICEBOOKCHOICE = wxNewId();
62
63BEGIN_EVENT_TABLE(wxChoicebook, wxBookCtrlBase)
64 EVT_SIZE(wxChoicebook::OnSize)
65 EVT_CHOICE(wxID_CHOICEBOOKCHOICE, wxChoicebook::OnChoiceSelected)
66END_EVENT_TABLE()
67
68// ============================================================================
69// wxChoicebook implementation
70// ============================================================================
71
72// ----------------------------------------------------------------------------
73// wxChoicebook creation
74// ----------------------------------------------------------------------------
75
76void wxChoicebook::Init()
77{
78 m_choice = NULL;
79 m_selection = wxNOT_FOUND;
80}
81
82bool
83wxChoicebook::Create(wxWindow *parent,
84 wxWindowID id,
85 const wxPoint& pos,
86 const wxSize& size,
87 long style,
88 const wxString& name)
89{
90 if ( (style & wxCHB_ALIGN_MASK) == wxCHB_DEFAULT )
91 {
92 style |= wxCHB_TOP;
93 }
94
95 // no border for this control, it doesn't look nice together with
96 // wxChoice border
97 style &= ~wxBORDER_MASK;
98 style |= wxBORDER_NONE;
99
100 if ( !wxControl::Create(parent, id, pos, size, style,
101 wxDefaultValidator, name) )
102 return false;
103
104 m_choice = new wxChoice
105 (
106 this,
107 wxID_CHOICEBOOKCHOICE,
108 wxDefaultPosition,
109 wxDefaultSize
110 );
111
112 return true;
113}
114
115// ----------------------------------------------------------------------------
116// wxChoicebook geometry management
117// ----------------------------------------------------------------------------
118
119wxSize wxChoicebook::GetChoiceSize() const
120{
121 const wxSize sizeClient = GetClientSize(),
122 sizeChoice = m_choice->GetBestFittingSize();
123
124 wxSize size;
125 if ( IsVertical() )
126 {
127 size.x = sizeClient.x;
128 size.y = sizeChoice.y;
129 }
130 else // left/right aligned
131 {
132 size.x = sizeChoice.x;
133 size.y = sizeClient.y;
134 }
135
136 return size;
137}
138
139wxRect wxChoicebook::GetPageRect() const
140{
141 const wxSize sizeChoice = m_choice->GetBestFittingSize();
142
143 wxPoint pt;
144 wxRect rectPage(pt, GetClientSize());
145 switch ( GetWindowStyle() & wxCHB_ALIGN_MASK )
146 {
147 default:
148 wxFAIL_MSG( _T("unexpected wxChoicebook alignment") );
149 // fall through
150
151 case wxCHB_TOP:
152 rectPage.y = sizeChoice.y + MARGIN;
153 // fall through
154
155 case wxCHB_BOTTOM:
156 rectPage.height -= sizeChoice.y + MARGIN;
157 break;
158
159 case wxCHB_LEFT:
160 rectPage.x = sizeChoice.x + MARGIN;
161 // fall through
162
163 case wxCHB_RIGHT:
164 rectPage.width -= sizeChoice.x + MARGIN;
165 break;
166 }
167
168 return rectPage;
169}
170
171void wxChoicebook::OnSize(wxSizeEvent& event)
172{
173 event.Skip();
174
175 if ( !m_choice )
176 {
177 // we're not fully created yet
178 return;
179 }
180
181 // resize the choice control and the page area to fit inside our new size
182 const wxSize sizeClient = GetClientSize(),
183 sizeChoice = GetChoiceSize();
184
185 wxPoint posChoice;
186 switch ( GetWindowStyle() & wxCHB_ALIGN_MASK )
187 {
188 default:
189 wxFAIL_MSG( _T("unexpected wxChoicebook alignment") );
190 // fall through
191
192 case wxCHB_TOP:
193 case wxCHB_LEFT:
194 // posChoice is already ok
195 break;
196
197 case wxCHB_BOTTOM:
198 posChoice.y = sizeClient.y - sizeChoice.y;
199 break;
200
201 case wxCHB_RIGHT:
202 posChoice.x = sizeClient.x - sizeChoice.x;
203 break;
204 }
205
206 m_choice->Move(posChoice);
207 m_choice->SetSize(sizeChoice);
208
209 // resize the currently shown page
210 if ( m_selection != wxNOT_FOUND )
211 {
212 wxWindow *page = m_pages[m_selection];
213 wxCHECK_RET( page, _T("NULL page in wxChoicebook?") );
214 page->SetSize(GetPageRect());
215 }
216}
217
218wxSize wxChoicebook::CalcSizeFromPage(const wxSize& sizePage) const
219{
220 // we need to add the size of the choice control and the margin
221 const wxSize sizeChoice = GetChoiceSize();
222
223 wxSize size = sizePage;
224 if ( IsVertical() )
225 {
226 size.y += sizeChoice.y + MARGIN;
227 }
228 else // left/right aligned
229 {
230 size.x += sizeChoice.x + MARGIN;
231 }
232
233 return size;
234}
235
236
237// ----------------------------------------------------------------------------
238// accessing the pages
239// ----------------------------------------------------------------------------
240
241bool wxChoicebook::SetPageText(size_t n, const wxString& strText)
242{
243 m_choice->SetString(n, strText);
244
245 return true;
246}
247
248wxString wxChoicebook::GetPageText(size_t n) const
249{
250 return m_choice->GetString(n);
251}
252
253int wxChoicebook::GetPageImage(size_t WXUNUSED(n)) const
254{
255 wxFAIL_MSG( _T("wxChoicebook::GetPageImage() not implemented") );
256
257 return wxNOT_FOUND;
258}
259
260bool wxChoicebook::SetPageImage(size_t WXUNUSED(n), int WXUNUSED(imageId))
261{
262 wxFAIL_MSG( _T("wxChoicebook::SetPageImage() not implemented") );
263
264 return false;
265}
266
267// ----------------------------------------------------------------------------
268// image list stuff
269// ----------------------------------------------------------------------------
270
271void wxChoicebook::SetImageList(wxImageList *imageList)
272{
273 // TODO: can be implemented in form of static bitmap near choice control
274
275 wxBookCtrlBase::SetImageList(imageList);
276}
277
278// ----------------------------------------------------------------------------
279// selection
280// ----------------------------------------------------------------------------
281
282int wxChoicebook::GetSelection() const
283{
284 return m_selection;
285}
286
287int wxChoicebook::SetSelection(size_t n)
288{
289 wxCHECK_MSG( IS_VALID_PAGE(n), wxNOT_FOUND,
290 wxT("invalid page index in wxChoicebook::SetSelection()") );
291
292 const int oldSel = m_selection;
293
294 if ( int(n) != m_selection )
295 {
296 wxChoicebookEvent event(wxEVT_COMMAND_CHOICEBOOK_PAGE_CHANGING, m_windowId);
297 event.SetSelection(n);
298 event.SetOldSelection(m_selection);
299 event.SetEventObject(this);
300 if ( !GetEventHandler()->ProcessEvent(event) || event.IsAllowed() )
301 {
302 if ( m_selection != wxNOT_FOUND )
303 m_pages[m_selection]->Hide();
304
305 wxWindow *page = m_pages[n];
306 page->SetSize(GetPageRect());
307 page->Show();
308
309 // change m_selection now to ignore the selection change event
310 m_selection = n;
311 m_choice->Select(n);
312
313 // program allows the page change
314 event.SetEventType(wxEVT_COMMAND_CHOICEBOOK_PAGE_CHANGED);
315 (void)GetEventHandler()->ProcessEvent(event);
316 }
317 }
318
319 return oldSel;
320}
321
322// ----------------------------------------------------------------------------
323// adding/removing the pages
324// ----------------------------------------------------------------------------
325
326bool
327wxChoicebook::InsertPage(size_t n,
328 wxWindow *page,
329 const wxString& text,
330 bool bSelect,
331 int imageId)
332{
333 if ( !wxBookCtrlBase::InsertPage(n, page, text, bSelect, imageId) )
334 return false;
335
336 m_choice->Insert(text, n);
337
338 // if the inserted page is before the selected one, we must update the
339 // index of the selected page
340 if ( int(n) <= m_selection )
341 {
342 // one extra page added
343 m_selection++;
344 m_choice->Select(m_selection);
345 }
346
347 // some page should be selected: either this one or the first one if there
348 // is still no selection
349 int selNew = -1;
350 if ( bSelect )
351 selNew = n;
352 else if ( m_selection == -1 )
353 selNew = 0;
354
355 if ( selNew != m_selection )
356 page->Hide();
357
358 if ( selNew != -1 )
359 SetSelection(selNew);
360
361 InvalidateBestSize();
362 return true;
363}
364
365wxWindow *wxChoicebook::DoRemovePage(size_t page)
366{
367 const int page_count = GetPageCount();
368 wxWindow *win = wxBookCtrlBase::DoRemovePage(page);
369
370 if ( win )
371 {
372 m_choice->Delete(page);
373
374 if (m_selection >= (int)page)
375 {
376 // force new sel valid if possible
377 int sel = m_selection - 1;
378 if (page_count == 1)
379 sel = wxNOT_FOUND;
380 else if ((page_count == 2) || (sel == -1))
381 sel = 0;
382
383 // force sel invalid if deleting current page - don't try to hide it
384 m_selection = (m_selection == (int)page) ? wxNOT_FOUND : m_selection - 1;
385
386 if ((sel != wxNOT_FOUND) && (sel != m_selection))
387 SetSelection(sel);
388 }
389 }
390
391 return win;
392}
393
394
395bool wxChoicebook::DeleteAllPages()
396{
397 m_choice->Clear();
398 return wxBookCtrlBase::DeleteAllPages();
399}
400
401// ----------------------------------------------------------------------------
402// wxChoicebook events
403// ----------------------------------------------------------------------------
404
405void wxChoicebook::OnChoiceSelected(wxCommandEvent& eventChoice)
406{
407 const int selNew = eventChoice.GetSelection();
408
409 if ( selNew == m_selection )
410 {
411 // this event can only come from our own Select(m_selection) below
412 // which we call when the page change is vetoed, so we should simply
413 // ignore it
414 return;
415 }
416
417 SetSelection(selNew);
418
419 // change wasn't allowed, return to previous state
420 if (m_selection != selNew)
421 m_choice->Select(m_selection);
422}
423
424#endif // wxUSE_CHOICEBOOK