X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e9c0df38e7bdf9dcc527833c6ed7ae30155c24cc..6e2fef031b643ceda4ff4bd6f1920ecb20780c6e:/src/generic/listbkg.cpp diff --git a/src/generic/listbkg.cpp b/src/generic/listbkg.cpp index b1fdca86aa..928f9b1026 100644 --- a/src/generic/listbkg.cpp +++ b/src/generic/listbkg.cpp @@ -33,6 +33,8 @@ #include "wx/listctrl.h" #include "wx/statline.h" #include "wx/listbook.h" +#include "wx/imaglist.h" +#include "wx/settings.h" // ---------------------------------------------------------------------------- // constants @@ -43,7 +45,7 @@ const wxCoord MARGIN = 5; // ---------------------------------------------------------------------------- -// various wxWindows macros +// various wxWidgets macros // ---------------------------------------------------------------------------- IMPLEMENT_DYNAMIC_CLASS(wxListbook, wxControl) @@ -51,11 +53,11 @@ IMPLEMENT_DYNAMIC_CLASS(wxListbookEvent, wxNotifyEvent) const wxEventType wxEVT_COMMAND_LISTBOOK_PAGE_CHANGING = wxNewEventType(); const wxEventType wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED = wxNewEventType(); +const int wxID_LISTBOOKLISTVIEW = wxNewId(); BEGIN_EVENT_TABLE(wxListbook, wxBookCtrl) EVT_SIZE(wxListbook::OnSize) - - EVT_LIST_ITEM_SELECTED(wxID_ANY, wxListbook::OnListSelected) + EVT_LIST_ITEM_SELECTED(wxID_LISTBOOKLISTVIEW, wxListbook::OnListSelected) END_EVENT_TABLE() // ============================================================================ @@ -69,7 +71,9 @@ END_EVENT_TABLE() void wxListbook::Init() { m_list = NULL; +#if wxUSE_LINE_IN_LISTBOOK m_line = NULL; +#endif // wxUSE_LINE_IN_LISTBOOK m_selection = wxNOT_FOUND; } @@ -90,6 +94,11 @@ wxListbook::Create(wxWindow *parent, #endif // __WXMAC__/!__WXMAC__ } + // no border for this control, it doesn't look nice together with + // wxListCtrl border + style &= ~wxBORDER_MASK; + style |= wxBORDER_NONE; + if ( !wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name) ) return false; @@ -97,21 +106,34 @@ wxListbook::Create(wxWindow *parent, m_list = new wxListView ( this, - -1, + wxID_LISTBOOKLISTVIEW, wxDefaultPosition, wxDefaultSize, - wxLC_ICON | wxLC_SINGLE_SEL + wxLC_ICON | wxLC_SINGLE_SEL | + (IsVertical() ? wxLC_ALIGN_LEFT : wxLC_ALIGN_TOP) ); +#if wxUSE_LINE_IN_LISTBOOK m_line = new wxStaticLine ( this, - -1, + wxID_ANY, wxDefaultPosition, wxDefaultSize, IsVertical() ? wxLI_HORIZONTAL : wxLI_VERTICAL ); - +#endif // wxUSE_LINE_IN_LISTBOOK + +#ifdef __WXMSW__ + // On XP with themes enabled the GetViewRect used in GetListSize to + // determine the space needed for the list view will incorrectly return + // (0,0,0,0) the first time. So send a pending event so OnSize wiull be + // called again after the window is ready to go. Technically we don't + // need to do this on non-XP windows, but if things are already sized + // correctly then nothing changes and so there is no harm. + wxSizeEvent evt; + GetEventHandler()->AddPendingEvent(evt); +#endif return true; } @@ -121,38 +143,18 @@ wxListbook::Create(wxWindow *parent, wxSize wxListbook::GetListSize() const { - const wxSize sizeClient = GetClientSize(); - - // we need to find the longest/tallest label - wxCoord widthMax = 0, - heightMax = 0; - const int count = m_list->GetItemCount(); - if ( count ) - { - for ( int i = 0; i < count; i++ ) - { - wxRect r; - m_list->GetItemRect(i, r); - - wxCoord w = r.x + r.width, - h = r.y + r.height; - - if ( w > widthMax ) - widthMax = w; - if ( h > heightMax ) - heightMax = h; - } - } + const wxSize sizeClient = GetClientSize(), + sizeList = m_list->GetViewRect().GetSize(); wxSize size; if ( IsVertical() ) { size.x = sizeClient.x; - size.y = heightMax; + size.y = sizeList.y; } else // left/right aligned { - size.x = widthMax + 10; + size.x = sizeList.x; size.y = sizeClient.y; } @@ -161,7 +163,7 @@ wxSize wxListbook::GetListSize() const wxRect wxListbook::GetPageRect() const { - const wxSize sizeList = GetListSize(); + const wxSize sizeList = m_list->GetSize(); wxRect rectPage(wxPoint(0, 0), GetClientSize()); switch ( GetWindowStyle() & wxLB_ALIGN_MASK ) @@ -192,6 +194,14 @@ wxRect wxListbook::GetPageRect() const void wxListbook::OnSize(wxSizeEvent& event) { + event.Skip(); + + if ( !m_list ) + { + // we're not fully created yet + return; + } + // resize the list control and the page area to fit inside our new size const wxSize sizeClient = GetClientSize(), sizeList = GetListSize(); @@ -217,8 +227,10 @@ void wxListbook::OnSize(wxSizeEvent& event) break; } - m_list->SetSize(posList.x, posList.y, sizeList.x, sizeList.y); + m_list->Move(posList.x, posList.y); + m_list->SetClientSize(sizeList.x, sizeList.y); +#if wxUSE_LINE_IN_LISTBOOK if ( m_line ) { wxRect rectLine(wxPoint(0, 0), sizeClient); @@ -248,26 +260,15 @@ void wxListbook::OnSize(wxSizeEvent& event) m_line->SetSize(rectLine); } +#endif // wxUSE_LINE_IN_LISTBOOK - // we should always have some selection if possible - if ( m_selection == wxNOT_FOUND && GetPageCount() ) - { - SetSelection(0); - } - - if ( m_selection != wxNOT_FOUND ) + // resize the currently shown page + if (m_selection != wxNOT_FOUND ) { wxWindow *page = m_pages[m_selection]; wxCHECK_RET( page, _T("NULL page in wxListbook?") ); - page->SetSize(GetPageRect()); - if ( !page->IsShown() ) - { - page->Show(); } - } - - event.Skip(); } wxSize wxListbook::CalcSizeFromPage(const wxSize& sizePage) const @@ -342,20 +343,26 @@ int wxListbook::SetSelection(size_t n) wxCHECK_MSG( n < GetPageCount(), wxNOT_FOUND, _T("invalid page index in wxListbook::SetSelection()") ); - int selOld = m_selection; + const int selOld = m_selection; if ( (int)n != m_selection ) { + if ( m_selection != wxNOT_FOUND ) + m_pages[m_selection]->Hide(); + wxWindow *page = m_pages[n]; + page->SetSize(GetPageRect()); + page->Show(); + + // change m_selection only now to ignore the selection change event m_selection = n; - m_list->Select(m_selection); - m_list->Focus(m_selection); + m_list->Select(n); + m_list->Focus(n); } return selOld; } - // ---------------------------------------------------------------------------- // adding/removing the pages // ---------------------------------------------------------------------------- @@ -372,10 +379,10 @@ wxListbook::InsertPage(size_t n, m_list->InsertItem(n, text, imageId); - if ( bSelect ) + // we should always have some selection if possible + if ( bSelect || (m_selection == wxNOT_FOUND) ) { - m_list->Select(n); - m_list->Focus(n); + SetSelection(n); } else // don't select this page { @@ -383,20 +390,46 @@ wxListbook::InsertPage(size_t n, page->Hide(); } + InvalidateBestSize(); return true; } wxWindow *wxListbook::DoRemovePage(size_t page) { + const int page_count = GetPageCount(); wxWindow *win = wxBookCtrl::DoRemovePage(page); + if ( win ) { m_list->DeleteItem(page); + + if (m_selection >= (int)page) + { + // force new sel valid if possible + int sel = m_selection - 1; + if (page_count == 1) + sel = wxNOT_FOUND; + else if ((page_count == 2) || (sel == -1)) + sel = 0; + + // force sel invalid if deleting current page - don't try to hide it + m_selection = (m_selection == (int)page) ? wxNOT_FOUND : m_selection - 1; + + if ((sel != wxNOT_FOUND) && (sel != m_selection)) + SetSelection(sel); + } } return win; } + +bool wxListbook::DeleteAllPages() +{ + m_list->DeleteAllItems(); + return wxBookCtrl::DeleteAllPages(); +} + // ---------------------------------------------------------------------------- // wxListbook events // ---------------------------------------------------------------------------- @@ -404,6 +437,7 @@ wxWindow *wxListbook::DoRemovePage(size_t page) void wxListbook::OnListSelected(wxListEvent& eventList) { const int selNew = eventList.GetIndex(); + const int selOld = m_selection; if ( selNew == m_selection ) { @@ -418,7 +452,7 @@ void wxListbook::OnListSelected(wxListEvent& eventList) eventIng.SetEventObject(this); eventIng.SetSelection(selNew); - eventIng.SetOldSelection(m_selection); + eventIng.SetOldSelection(selOld); if ( GetEventHandler()->ProcessEvent(eventIng) && !eventIng.IsAllowed() ) { m_list->Select(m_selection); @@ -426,17 +460,13 @@ void wxListbook::OnListSelected(wxListEvent& eventList) } // change allowed: do change the page and notify the user about it - if ( m_selection != wxNOT_FOUND ) - m_pages[m_selection]->Hide(); - wxWindow *page = m_pages[m_selection = selNew]; - page->SetSize(GetPageRect()); - page->Show(); + SetSelection(selNew); wxListbookEvent eventEd(wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED, GetId()); eventEd.SetEventObject(this); eventEd.SetSelection(selNew); - eventEd.SetOldSelection(m_selection); + eventEd.SetOldSelection(selOld); (void)GetEventHandler()->ProcessEvent(eventEd); }