X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9804d5404a9607cda3d08ec8225f52f78b78bc72..89e1de6441845de971433531a7286d5bea06c3f5:/src/generic/listbkg.cpp diff --git a/src/generic/listbkg.cpp b/src/generic/listbkg.cpp index 67059a7197..f829305777 100644 --- a/src/generic/listbkg.cpp +++ b/src/generic/listbkg.cpp @@ -36,6 +36,12 @@ #include "wx/statline.h" #include "wx/imaglist.h" +// FIXME: native OS X wxListCtrl hangs if this code is used for it so disable +// it for now +#if !defined(__WXMAC__) + #define CAN_USE_REPORT_VIEW +#endif + // ---------------------------------------------------------------------------- // various wxWidgets macros // ---------------------------------------------------------------------------- @@ -48,17 +54,13 @@ // ---------------------------------------------------------------------------- IMPLEMENT_DYNAMIC_CLASS(wxListbook, wxBookCtrlBase) -IMPLEMENT_DYNAMIC_CLASS(wxListbookEvent, wxNotifyEvent) -#if !WXWIN_COMPATIBILITY_EVENT_TYPES -const wxEventType wxEVT_COMMAND_LISTBOOK_PAGE_CHANGING = wxNewEventType(); -const wxEventType wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED = wxNewEventType(); -#endif -const int wxID_LISTBOOKLISTVIEW = wxNewId(); +wxDEFINE_EVENT( wxEVT_COMMAND_LISTBOOK_PAGE_CHANGING, wxBookCtrlEvent ); +wxDEFINE_EVENT( wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED, wxBookCtrlEvent ); BEGIN_EVENT_TABLE(wxListbook, wxBookCtrlBase) EVT_SIZE(wxListbook::OnSize) - EVT_LIST_ITEM_SELECTED(wxID_LISTBOOKLISTVIEW, wxListbook::OnListSelected) + EVT_LIST_ITEM_SELECTED(wxID_ANY, wxListbook::OnListSelected) END_EVENT_TABLE() // ============================================================================ @@ -103,13 +105,21 @@ wxListbook::Create(wxWindow *parent, m_bookctrl = new wxListView ( this, - wxID_LISTBOOKLISTVIEW, + wxID_ANY, wxDefaultPosition, wxDefaultSize, - wxLC_ICON | wxLC_SINGLE_SEL | - (IsVertical() ? wxLC_ALIGN_LEFT : wxLC_ALIGN_TOP) + wxLC_SINGLE_SEL | +#ifdef CAN_USE_REPORT_VIEW + GetListCtrlReportViewFlags() +#else // !CAN_USE_REPORT_VIEW + GetListCtrlIconViewFlags() +#endif // CAN_USE_REPORT_VIEW/!CAN_USE_REPORT_VIEW ); +#ifdef CAN_USE_REPORT_VIEW + GetListView()->InsertColumn(0, wxT("Pages")); +#endif // CAN_USE_REPORT_VIEW + #ifdef __WXMSW__ // On XP with themes enabled the GetViewRect used in GetControllerSize() to // determine the space needed for the list view will incorrectly return @@ -124,31 +134,27 @@ wxListbook::Create(wxWindow *parent, } // ---------------------------------------------------------------------------- -// wxListbook geometry management +// wxListCtrl flags // ---------------------------------------------------------------------------- -wxSize wxListbook::GetControllerSize() const +long wxListbook::GetListCtrlIconViewFlags() const { - const wxSize sizeClient = GetClientSize(), - sizeBorder = m_bookctrl->GetSize() - m_bookctrl->GetClientSize(), - sizeList = GetListView()->GetViewRect().GetSize() + sizeBorder; + return (IsVertical() ? wxLC_ALIGN_LEFT : wxLC_ALIGN_TOP) | wxLC_ICON; +} - wxSize size; +#ifdef CAN_USE_REPORT_VIEW - if ( IsVertical() ) - { - size.x = sizeClient.x; - size.y = sizeList.y; - } - else // left/right aligned - { - size.x = sizeList.x; - size.y = sizeClient.y; - } - - return size; +long wxListbook::GetListCtrlReportViewFlags() const +{ + return wxLC_REPORT | wxLC_NO_HEADER; } +#endif // CAN_USE_REPORT_VIEW + +// ---------------------------------------------------------------------------- +// wxListbook geometry management +// ---------------------------------------------------------------------------- + void wxListbook::OnSize(wxSizeEvent& event) { // arrange the icons before calling SetClientSize(), otherwise it wouldn't @@ -156,9 +162,11 @@ void wxListbook::OnSize(wxSizeEvent& event) // under MSW, we'd finish with an ugly looking list control with both // vertical and horizontal scrollbar (with one of them being added because // the other one is not accounted for in client size computations) - wxListView *list = GetListView(); - if (list) list->Arrange(); - wxBookCtrlBase::OnSize(event); + wxListView * const list = GetListView(); + if ( list ) + list->Arrange(); + + event.Skip(); } int wxListbook::HitTest(const wxPoint& pt, long *flags) const @@ -173,7 +181,7 @@ int wxListbook::HitTest(const wxPoint& pt, long *flags) const const wxPoint listPt = list->ScreenToClient(ClientToScreen(pt)); // is the point inside list control? - if ( wxRect(list->GetSize()).Inside(listPt) ) + if ( wxRect(list->GetSize()).Contains(listPt) ) { int flagsList; pagePos = list->HitTest(listPt, flagsList); @@ -193,32 +201,21 @@ int wxListbook::HitTest(const wxPoint& pt, long *flags) const } else // not over list control at all { - if ( flags && GetPageRect().Inside(pt) ) + if ( flags && GetPageRect().Contains(pt) ) *flags |= wxBK_HITTEST_ONPAGE; } return pagePos; } -wxSize wxListbook::CalcSizeFromPage(const wxSize& sizePage) const +void wxListbook::UpdateSize() { - // we need to add the size of the list control and the border between - const wxSize sizeList = GetControllerSize(); - - wxSize size = sizePage; - if ( IsVertical() ) - { - size.y += sizeList.y + GetInternalBorder(); - } - else // left/right aligned - { - size.x += sizeList.x + GetInternalBorder(); - } - - return size; + // we should find a more elegant way to force a layout than generating this + // dummy event + wxSizeEvent sz(GetSize(), GetId()); + GetEventHandler()->ProcessEvent(sz); } - // ---------------------------------------------------------------------------- // accessing the pages // ---------------------------------------------------------------------------- @@ -235,11 +232,19 @@ wxString wxListbook::GetPageText(size_t n) const return GetListView()->GetItemText(n); } -int wxListbook::GetPageImage(size_t WXUNUSED(n)) const +int wxListbook::GetPageImage(size_t n) const { - wxFAIL_MSG( _T("wxListbook::GetPageImage() not implemented") ); + wxListItem item; + item.SetId(n); - return wxNOT_FOUND; + if (GetListView()->GetItem(item)) + { + return item.GetImage(); + } + else + { + return wxNOT_FOUND; + } } bool wxListbook::SetPageImage(size_t n, int imageId) @@ -253,7 +258,37 @@ bool wxListbook::SetPageImage(size_t n, int imageId) void wxListbook::SetImageList(wxImageList *imageList) { - GetListView()->SetImageList(imageList, wxIMAGE_LIST_NORMAL); +#ifdef CAN_USE_REPORT_VIEW + wxListView * const list = GetListView(); + + // If imageList presence has changed, we update the list control view + if ( (imageList != NULL) != (GetImageList() != NULL) ) + { + // Preserve the selection which is lost when changing the mode + const int oldSel = GetSelection(); + + // Update the style to use icon view for images, report view otherwise + long style = wxLC_SINGLE_SEL; + if ( imageList ) + { + style |= GetListCtrlIconViewFlags(); + } + else // no image list + { + style |= GetListCtrlReportViewFlags(); + } + + list->SetWindowStyleFlag(style); + if ( !imageList ) + list->InsertColumn(0, wxT("Pages")); + + // Restore selection + if ( oldSel != wxNOT_FOUND ) + SetSelection(oldSel); + } + + list->SetImageList(imageList, wxIMAGE_LIST_NORMAL); +#endif // CAN_USE_REPORT_VIEW wxBookCtrlBase::SetImageList(imageList); } @@ -262,47 +297,29 @@ void wxListbook::SetImageList(wxImageList *imageList) // selection // ---------------------------------------------------------------------------- +void wxListbook::UpdateSelectedPage(size_t newsel) +{ + m_selection = newsel; + GetListView()->Select(newsel); + GetListView()->Focus(newsel); +} + int wxListbook::GetSelection() const { return m_selection; } -int wxListbook::SetSelection(size_t n) +wxBookCtrlEvent* wxListbook::CreatePageChangingEvent() const { - wxCHECK_MSG( IS_VALID_PAGE(n), wxNOT_FOUND, - wxT("invalid page index in wxListbook::SetSelection()") ); - - const int oldSel = m_selection; - - if ( int(n) != m_selection ) - { - wxListbookEvent event(wxEVT_COMMAND_LISTBOOK_PAGE_CHANGING, m_windowId); - event.SetSelection(n); - event.SetOldSelection(m_selection); - event.SetEventObject(this); - if ( !GetEventHandler()->ProcessEvent(event) || event.IsAllowed() ) - { - if ( m_selection != wxNOT_FOUND ) - m_pages[m_selection]->Hide(); - - wxWindow *page = m_pages[n]; - page->SetSize(GetPageRect()); - page->Show(); - - // change m_selection now to ignore the selection change event - m_selection = n; - GetListView()->Select(n); - GetListView()->Focus(n); - - // program allows the page change - event.SetEventType(wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED); - (void)GetEventHandler()->ProcessEvent(event); - } - } + return new wxBookCtrlEvent(wxEVT_COMMAND_LISTBOOK_PAGE_CHANGING, m_windowId); +} - return oldSel; +void wxListbook::MakeChangedEvent(wxBookCtrlEvent &event) +{ + event.SetEventType(wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED); } + // ---------------------------------------------------------------------------- // adding/removing the pages // ---------------------------------------------------------------------------- @@ -343,15 +360,8 @@ wxListbook::InsertPage(size_t n, if ( selNew != -1 ) SetSelection(selNew); - InvalidateBestSize(); - // GetListView()->InvalidateBestSize(); - GetListView()->Arrange(); + UpdateSize(); - if (GetPageCount() == 1) - { - wxSizeEvent sz(GetSize(), GetId()); - ProcessEvent(sz); - } return true; } @@ -381,11 +391,7 @@ wxWindow *wxListbook::DoRemovePage(size_t page) } GetListView()->Arrange(); - if (GetPageCount() == 0) - { - wxSizeEvent sz(GetSize(), GetId()); - ProcessEvent(sz); - } + UpdateSize(); } return win; @@ -400,8 +406,7 @@ bool wxListbook::DeleteAllPages() m_selection = -1; - wxSizeEvent sz(GetSize(), GetId()); - ProcessEvent(sz); + UpdateSize(); return true; } @@ -412,6 +417,12 @@ bool wxListbook::DeleteAllPages() void wxListbook::OnListSelected(wxListEvent& eventList) { + if ( eventList.GetEventObject() != m_bookctrl ) + { + eventList.Skip(); + return; + } + const int selNew = eventList.GetIndex(); if ( selNew == m_selection )