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 
   8 // Copyright:   (c) Vadim Zeitlin, Wlodzimierz Skiba 
   9 // Licence:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  29 #include "wx/choice.h" 
  30 #include "wx/choicebk.h" 
  31 #include "wx/imaglist.h" 
  32 #include "wx/settings.h" 
  34 // ---------------------------------------------------------------------------- 
  36 // ---------------------------------------------------------------------------- 
  38 // margin between the choice and the page 
  39 #if defined(__WXWINCE__) 
  40 const wxCoord MARGIN 
= 1; 
  42 const wxCoord MARGIN 
= 5; 
  45 // ---------------------------------------------------------------------------- 
  46 // various wxWidgets macros 
  47 // ---------------------------------------------------------------------------- 
  49 // check that the page index is valid 
  50 #define IS_VALID_PAGE(nPage) ((nPage) < GetPageCount()) 
  52 // ---------------------------------------------------------------------------- 
  54 // ---------------------------------------------------------------------------- 
  56 IMPLEMENT_DYNAMIC_CLASS(wxChoicebook
, wxControl
) 
  57 IMPLEMENT_DYNAMIC_CLASS(wxChoicebookEvent
, wxNotifyEvent
) 
  59 const wxEventType wxEVT_COMMAND_CHOICEBOOK_PAGE_CHANGING 
= wxNewEventType(); 
  60 const wxEventType wxEVT_COMMAND_CHOICEBOOK_PAGE_CHANGED 
= wxNewEventType(); 
  61 const int wxID_CHOICEBOOKCHOICE 
= wxNewId(); 
  63 BEGIN_EVENT_TABLE(wxChoicebook
, wxBookCtrlBase
) 
  64     EVT_SIZE(wxChoicebook::OnSize
) 
  65     EVT_CHOICE(wxID_CHOICEBOOKCHOICE
, wxChoicebook::OnChoiceSelected
) 
  68 // ============================================================================ 
  69 // wxChoicebook implementation 
  70 // ============================================================================ 
  72 // ---------------------------------------------------------------------------- 
  73 // wxChoicebook creation 
  74 // ---------------------------------------------------------------------------- 
  76 void wxChoicebook::Init() 
  79     m_selection 
= wxNOT_FOUND
; 
  83 wxChoicebook::Create(wxWindow 
*parent
, 
  90     if ( (style 
& wxCHB_ALIGN_MASK
) == wxCHB_DEFAULT 
) 
  95     // no border for this control, it doesn't look nice together with 
  97     style 
&= ~wxBORDER_MASK
; 
  98     style 
|= wxBORDER_NONE
; 
 100     if ( !wxControl::Create(parent
, id
, pos
, size
, style
, 
 101                             wxDefaultValidator
, name
) ) 
 104     m_choice 
= new wxChoice
 
 107                     wxID_CHOICEBOOKCHOICE
, 
 115 // ---------------------------------------------------------------------------- 
 116 // wxChoicebook geometry management 
 117 // ---------------------------------------------------------------------------- 
 119 wxSize 
wxChoicebook::GetChoiceSize() const 
 121     const wxSize sizeClient 
= GetClientSize(), 
 122                  sizeChoice 
= m_choice
->GetBestFittingSize(); 
 127         size
.x 
= sizeClient
.x
; 
 128         size
.y 
= sizeChoice
.y
; 
 130     else // left/right aligned 
 132         size
.x 
= sizeChoice
.x
; 
 133         size
.y 
= sizeClient
.y
; 
 139 wxRect 
wxChoicebook::GetPageRect() const 
 141     const wxSize sizeChoice 
= m_choice
->GetBestFittingSize(); 
 144     wxRect 
rectPage(pt
, GetClientSize()); 
 145     switch ( GetWindowStyle() & wxCHB_ALIGN_MASK 
) 
 148             wxFAIL_MSG( _T("unexpected wxChoicebook alignment") ); 
 152             rectPage
.y 
= sizeChoice
.y 
+ MARGIN
; 
 156             rectPage
.height 
-= sizeChoice
.y 
+ MARGIN
; 
 160             rectPage
.x 
= sizeChoice
.x 
+ MARGIN
; 
 164             rectPage
.width 
-= sizeChoice
.x 
+ MARGIN
; 
 171 void wxChoicebook::OnSize(wxSizeEvent
& event
) 
 177         // we're not fully created yet 
 181     // resize the choice control and the page area to fit inside our new size 
 182     const wxSize sizeClient 
= GetClientSize(), 
 183                  sizeChoice 
= GetChoiceSize(); 
 186     switch ( GetWindowStyle() & wxCHB_ALIGN_MASK 
) 
 189             wxFAIL_MSG( _T("unexpected wxChoicebook alignment") ); 
 194             // posChoice is already ok 
 198             posChoice
.y 
= sizeClient
.y 
- sizeChoice
.y
; 
 202             posChoice
.x 
= sizeClient
.x 
- sizeChoice
.x
; 
 206     m_choice
->Move(posChoice
); 
 207     m_choice
->SetSize(sizeChoice
); 
 209     // resize the currently shown page 
 210     if ( m_selection 
!= wxNOT_FOUND 
) 
 212         wxWindow 
*page 
= m_pages
[m_selection
]; 
 213         wxCHECK_RET( page
, _T("NULL page in wxChoicebook?") ); 
 214         page
->SetSize(GetPageRect()); 
 218 wxSize 
wxChoicebook::CalcSizeFromPage(const wxSize
& sizePage
) const 
 220     // we need to add the size of the choice control and the margin 
 221     const wxSize sizeChoice 
= GetChoiceSize(); 
 223     wxSize size 
= sizePage
; 
 226         size
.y 
+= sizeChoice
.y 
+ MARGIN
; 
 228     else // left/right aligned 
 230         size
.x 
+= sizeChoice
.x 
+ MARGIN
; 
 237 // ---------------------------------------------------------------------------- 
 238 // accessing the pages 
 239 // ---------------------------------------------------------------------------- 
 241 bool wxChoicebook::SetPageText(size_t n
, const wxString
& strText
) 
 243     m_choice
->SetString(n
, strText
); 
 248 wxString 
wxChoicebook::GetPageText(size_t n
) const 
 250     return m_choice
->GetString(n
); 
 253 int wxChoicebook::GetPageImage(size_t WXUNUSED(n
)) const 
 255     wxFAIL_MSG( _T("wxChoicebook::GetPageImage() not implemented") ); 
 260 bool wxChoicebook::SetPageImage(size_t WXUNUSED(n
), int WXUNUSED(imageId
)) 
 262     wxFAIL_MSG( _T("wxChoicebook::SetPageImage() not implemented") ); 
 267 // ---------------------------------------------------------------------------- 
 269 // ---------------------------------------------------------------------------- 
 271 void wxChoicebook::SetImageList(wxImageList 
*imageList
) 
 273     // TODO: can be implemented in form of static bitmap near choice control 
 275     wxBookCtrlBase::SetImageList(imageList
); 
 278 // ---------------------------------------------------------------------------- 
 280 // ---------------------------------------------------------------------------- 
 282 int wxChoicebook::GetSelection() const 
 287 int wxChoicebook::SetSelection(size_t n
) 
 289     wxCHECK_MSG( IS_VALID_PAGE(n
), wxNOT_FOUND
, 
 290                  wxT("invalid page index in wxChoicebook::SetSelection()") ); 
 292     const int oldSel 
= m_selection
; 
 294     if ( int(n
) != m_selection 
) 
 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() ) 
 302             if ( m_selection 
!= wxNOT_FOUND 
) 
 303                 m_pages
[m_selection
]->Hide(); 
 305             wxWindow 
*page 
= m_pages
[n
]; 
 306             page
->SetSize(GetPageRect()); 
 309             // change m_selection now to ignore the selection change event 
 313             // program allows the page change 
 314             event
.SetEventType(wxEVT_COMMAND_CHOICEBOOK_PAGE_CHANGED
); 
 315             (void)GetEventHandler()->ProcessEvent(event
); 
 322 // ---------------------------------------------------------------------------- 
 323 // adding/removing the pages 
 324 // ---------------------------------------------------------------------------- 
 327 wxChoicebook::InsertPage(size_t n
, 
 329                          const wxString
& text
, 
 333     if ( !wxBookCtrlBase::InsertPage(n
, page
, text
, bSelect
, imageId
) ) 
 336     m_choice
->Insert(text
, n
); 
 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 
) 
 342         // one extra page added 
 344         m_choice
->Select(m_selection
); 
 347     // some page should be selected: either this one or the first one if there 
 348     // is still no selection 
 352     else if ( m_selection 
== -1 ) 
 355     if ( selNew 
!= m_selection 
) 
 359         SetSelection(selNew
); 
 361     InvalidateBestSize(); 
 365 wxWindow 
*wxChoicebook::DoRemovePage(size_t page
) 
 367     const size_t page_count 
= GetPageCount(); 
 368     wxWindow 
*win 
= wxBookCtrlBase::DoRemovePage(page
); 
 372         m_choice
->Delete(page
); 
 374         if (m_selection 
>= (int)page
) 
 376             // force new sel valid if possible 
 377             int sel 
= m_selection 
- 1; 
 380             else if ((page_count 
== 2) || (sel 
== -1)) 
 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; 
 386             if ((sel 
!= wxNOT_FOUND
) && (sel 
!= m_selection
)) 
 395 bool wxChoicebook::DeleteAllPages() 
 398     return wxBookCtrlBase::DeleteAllPages(); 
 401 // ---------------------------------------------------------------------------- 
 402 // wxChoicebook events 
 403 // ---------------------------------------------------------------------------- 
 405 void wxChoicebook::OnChoiceSelected(wxCommandEvent
& eventChoice
) 
 407     const int selNew 
= eventChoice
.GetSelection(); 
 409     if ( selNew 
== m_selection 
) 
 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 
 417     SetSelection(selNew
); 
 419     // change wasn't allowed, return to previous state 
 420     if (m_selection 
!= selNew
) 
 421         m_choice
->Select(m_selection
); 
 424 #endif // wxUSE_CHOICEBOOK