X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2ddb4d13585d5235556119fb1937273da9e433a3..ae6a64b6af83a95769363424e09d117a96a15a4c:/src/common/bookctrl.cpp diff --git a/src/common/bookctrl.cpp b/src/common/bookctrl.cpp index 2431b05ac5..db698594dd 100644 --- a/src/common/bookctrl.cpp +++ b/src/common/bookctrl.cpp @@ -42,6 +42,9 @@ IMPLEMENT_ABSTRACT_CLASS(wxBookCtrlBase, wxControl) BEGIN_EVENT_TABLE(wxBookCtrlBase, wxControl) EVT_SIZE(wxBookCtrlBase::OnSize) +#if wxUSE_HELP + EVT_HELP(wxID_ANY, wxBookCtrlBase::OnHelp) +#endif // wxUSE_HELP END_EVENT_TABLE() // ---------------------------------------------------------------------------- @@ -53,12 +56,16 @@ void wxBookCtrlBase::Init() m_bookctrl = NULL; m_imageList = NULL; m_ownsImageList = false; + m_fitToCurrentPage = false; #if defined(__WXWINCE__) m_internalBorder = 1; #else m_internalBorder = 5; #endif + + m_controlMargin = 0; + m_controlSizer = NULL; } bool @@ -144,6 +151,9 @@ wxSize wxBookCtrlBase::DoGetBestSize() const } } + if (m_fitToCurrentPage && GetCurrentPage()) + bestSize = GetCurrentPage()->GetBestSize(); + // convert display area to window area, adding the size necessary for the // tabs wxSize best = CalcSizeFromPage(bestSize); @@ -151,6 +161,64 @@ wxSize wxBookCtrlBase::DoGetBestSize() const return best; } +#if wxUSE_HELP + +void wxBookCtrlBase::OnHelp(wxHelpEvent& event) +{ + // determine where does this even originate from to avoid redirecting it + // back to the page which generated it (resulting in an infinite loop) + + // notice that we have to check in the hard(er) way instead of just testing + // if the event object == this because the book control can have other + // subcontrols inside it (e.g. wxSpinButton in case of a notebook in wxUniv) + wxWindow *source = wxStaticCast(event.GetEventObject(), wxWindow); + while ( source && source != this && source->GetParent() != this ) + { + source = source->GetParent(); + } + + if ( source && m_pages.Index(source) == wxNOT_FOUND ) + { + // this event is for the book control itself, redirect it to the + // corresponding page + wxWindow *page = NULL; + + if ( event.GetOrigin() == wxHelpEvent::Origin_HelpButton ) + { + // show help for the page under the mouse + const int pagePos = HitTest(ScreenToClient(event.GetPosition())); + + if ( pagePos != wxNOT_FOUND) + { + page = GetPage((size_t)pagePos); + } + } + else // event from keyboard or unknown source + { + // otherwise show the current page help + page = GetCurrentPage(); + } + + if ( page ) + { + // change event object to the page to avoid infinite recursion if + // we get this event ourselves if the page doesn't handle it + event.SetEventObject(page); + + if ( page->GetEventHandler()->ProcessEvent(event) ) + { + // don't call event.Skip() + return; + } + } + } + //else: event coming from one of our pages already + + event.Skip(); +} + +#endif // wxUSE_HELP + // ---------------------------------------------------------------------------- // pages management // ---------------------------------------------------------------------------- @@ -168,6 +236,9 @@ wxBookCtrlBase::InsertPage(size_t nPage, _T("invalid page index in wxBookCtrlBase::InsertPage()") ); m_pages.Insert(page, nPage); + if ( page ) + page->SetSize(GetPageRect()); + InvalidateBestSize(); return true; @@ -226,6 +297,7 @@ wxRect wxBookCtrlBase::GetPageRect() const wxPoint pt; wxRect rectPage(pt, GetClientSize()); + switch ( GetWindowStyle() & wxBK_ALIGN_MASK ) { default: @@ -238,6 +310,8 @@ wxRect wxBookCtrlBase::GetPageRect() const case wxBK_BOTTOM: rectPage.height -= size.y + GetInternalBorder(); + if (rectPage.height < 0) + rectPage.height = 0; break; case wxBK_LEFT: @@ -246,63 +320,84 @@ wxRect wxBookCtrlBase::GetPageRect() const case wxBK_RIGHT: rectPage.width -= size.x + GetInternalBorder(); + if (rectPage.width < 0) + rectPage.width = 0; break; } return rectPage; } -void wxBookCtrlBase::OnSize(wxSizeEvent& event) +// Lay out controls +void wxBookCtrlBase::DoSize() { - event.Skip(); - if ( !m_bookctrl ) { // we're not fully created yet or OnSize() should be hidden by derived class return; } - // resize controller and the page area to fit inside our new size - const wxSize sizeClient( GetClientSize() ), - sizeBorder( m_bookctrl->GetSize() - m_bookctrl->GetClientSize() ), - sizeCtrl( GetControllerSize() ); - - m_bookctrl->SetClientSize( sizeCtrl.x - sizeBorder.x, sizeCtrl.y - sizeBorder.y ); - - const wxSize sizeNew = m_bookctrl->GetSize(); - wxPoint posCtrl; - switch ( GetWindowStyle() & wxBK_ALIGN_MASK ) + if (GetSizer()) + Layout(); + else { - default: - wxFAIL_MSG( _T("unexpected alignment") ); - // fall through + // resize controller and the page area to fit inside our new size + const wxSize sizeClient( GetClientSize() ), + sizeBorder( m_bookctrl->GetSize() - m_bookctrl->GetClientSize() ), + sizeCtrl( GetControllerSize() ); - case wxBK_TOP: - case wxBK_LEFT: - // posCtrl is already ok - break; + m_bookctrl->SetClientSize( sizeCtrl.x - sizeBorder.x, sizeCtrl.y - sizeBorder.y ); - case wxBK_BOTTOM: - posCtrl.y = sizeClient.y - sizeNew.y; - break; + const wxSize sizeNew = m_bookctrl->GetSize(); + wxPoint posCtrl; + switch ( GetWindowStyle() & wxBK_ALIGN_MASK ) + { + default: + wxFAIL_MSG( _T("unexpected alignment") ); + // fall through + + case wxBK_TOP: + case wxBK_LEFT: + // posCtrl is already ok + break; + + case wxBK_BOTTOM: + posCtrl.y = sizeClient.y - sizeNew.y; + break; + + case wxBK_RIGHT: + posCtrl.x = sizeClient.x - sizeNew.x; + break; + } - case wxBK_RIGHT: - posCtrl.x = sizeClient.x - sizeNew.x; - break; + if ( m_bookctrl->GetPosition() != posCtrl ) + m_bookctrl->Move(posCtrl); } - if ( m_bookctrl->GetPosition() != posCtrl ) - m_bookctrl->Move(posCtrl); - - // resize the currently shown page - if (GetSelection() != wxNOT_FOUND ) + // resize all pages to fit the new control size + const wxRect pageRect = GetPageRect(); + const unsigned pagesCount = m_pages.Count(); + for ( unsigned int i = 0; i < pagesCount; ++i ) { - wxWindow *page = m_pages[GetSelection()]; - wxCHECK_RET( page, _T("NULL page?") ); - page->SetSize(GetPageRect()); + wxWindow * const page = m_pages[i]; + if ( !page ) + { + wxASSERT_MSG( AllowNullPage(), + _T("Null page in a control that does not allow null pages?") ); + continue; + } + + page->SetSize(pageRect); } } +void wxBookCtrlBase::OnSize(wxSizeEvent& event) +{ + event.Skip(); + + DoSize(); +} + wxSize wxBookCtrlBase::GetControllerSize() const { if(!m_bookctrl) @@ -328,4 +423,52 @@ wxSize wxBookCtrlBase::GetControllerSize() const return size; } +int wxBookCtrlBase::DoSetSelection(size_t n, int flags) +{ + wxCHECK_MSG( n < GetPageCount(), wxNOT_FOUND, + wxT("invalid page index in wxBookCtrlBase::DoSetSelection()") ); + + const int oldSel = GetSelection(); + + if ( oldSel != wxNOT_FOUND && n != (size_t)oldSel ) + { + wxBookCtrlBaseEvent *event = CreatePageChangingEvent(); + bool allowed = false; + + if ( flags & SetSelection_SendEvent ) + { + event->SetSelection(n); + event->SetOldSelection(oldSel); + event->SetEventObject(this); + + allowed = !GetEventHandler()->ProcessEvent(*event) || event->IsAllowed(); + } + + if ( !(flags & SetSelection_SendEvent) || allowed) + { + if ( oldSel != wxNOT_FOUND ) + m_pages[oldSel]->Hide(); + + wxWindow *page = m_pages[n]; + page->SetSize(GetPageRect()); + page->Show(); + + // change selection now to ignore the selection change event + UpdateSelectedPage(n); + + if ( flags & SetSelection_SendEvent ) + { + // program allows the page change + MakeChangedEvent(*event); + (void)GetEventHandler()->ProcessEvent(*event); + } + } + + delete event; + } + + return oldSel; +} + + #endif // wxUSE_BOOKCTRL