const wxCoord MARGIN = 5;
// ----------------------------------------------------------------------------
-// various wxWindows macros
+// various wxWidgets macros
// ----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxListbook, wxControl)
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()
// ============================================================================
void wxListbook::Init()
{
m_list = NULL;
+#if wxUSE_LINE_IN_LISTBOOK
m_line = NULL;
+#endif // wxUSE_LINE_IN_LISTBOOK
m_selection = wxNOT_FOUND;
}
#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;
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;
}
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;
-
- if ( widthMax >= sizeClient.x )
- {
- // account for the scrollbar
- size.y += wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y);
- }
+ size.y = sizeList.y;
}
else // left/right aligned
{
- // +10 is due to an apparent bug in wxListCtrl::GetItemRect() but I
- // can't fix it there right now so just add a fudge here...
- size.x = widthMax + 10;
+ size.x = sizeList.x;
size.y = sizeClient.y;
-
- if ( heightMax >= sizeClient.y )
- {
- // account for the scrollbar
- size.x += wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
- }
}
return size;
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 )
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);
m_line->SetSize(rectLine);
}
+#endif // wxUSE_LINE_IN_LISTBOOK
// we should always have some selection if possible
if ( m_selection == wxNOT_FOUND && GetPageCount() )
if ( (int)n != m_selection )
{
- m_selection = n;
+ m_list->Select(n);
+ m_list->Focus(n);
- m_list->Select(m_selection);
- m_list->Focus(m_selection);
+ // change m_selection only now, otherwise OnListSelected() would ignore
+ // the selection change event
+ m_selection = n;
}
return selOld;
page->Hide();
}
+ InvalidateBestSize();
return true;
}