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