added support for wxLC_ALIGN_LEFT/TOP

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@23586 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2003-09-14 20:40:26 +00:00
parent eb6c4508c9
commit 13602ebd04

View File

@ -117,10 +117,17 @@ static const int LINE_SPACING = 0;
static const int EXTRA_WIDTH = 3; static const int EXTRA_WIDTH = 3;
static const int EXTRA_HEIGHT = 4; static const int EXTRA_HEIGHT = 4;
// margin between the window and the items
static const int EXTRA_BORDER_X = 2;
static const int EXTRA_BORDER_Y = 2;
// offset for the header window // offset for the header window
static const int HEADER_OFFSET_X = 1; static const int HEADER_OFFSET_X = 1;
static const int HEADER_OFFSET_Y = 1; static const int HEADER_OFFSET_Y = 1;
// margin between rows of icons in [small] icon view
static const int MARGIN_BETWEEN_ROWS = 6;
// when autosizing the columns, add some slack // when autosizing the columns, add some slack
static const int AUTOSIZE_COL_MARGIN = 10; static const int AUTOSIZE_COL_MARGIN = 10;
@ -305,7 +312,7 @@ public:
void CalculateSize( wxDC *dc, int spacing ); void CalculateSize( wxDC *dc, int spacing );
// remember the position this line appears at // remember the position this line appears at
void SetPosition( int x, int y, int window_width, int spacing ); void SetPosition( int x, int y, int spacing );
// wxListCtrl API // wxListCtrl API
@ -724,8 +731,6 @@ public:
bool m_dirty; bool m_dirty;
wxColour *m_highlightColour; wxColour *m_highlightColour;
int m_xScroll,
m_yScroll;
wxImageListType *m_small_image_list; wxImageListType *m_small_image_list;
wxImageListType *m_normal_image_list; wxImageListType *m_normal_image_list;
int m_small_spacing; int m_small_spacing;
@ -753,9 +758,6 @@ protected:
// common part of all ctors // common part of all ctors
void Init(); void Init();
// intiialize m_[xy]Scroll
void InitScrolling();
// get the line data for the given index // get the line data for the given index
wxListLineData *GetLine(size_t n) const wxListLineData *GetLine(size_t n) const
{ {
@ -1214,9 +1216,7 @@ void wxListLineData::CalculateSize( wxDC *dc, int spacing )
} }
} }
void wxListLineData::SetPosition( int x, int y, void wxListLineData::SetPosition( int x, int y, int spacing )
int WXUNUSED(window_width),
int spacing )
{ {
wxListItemDataList::compatibility_iterator node = m_items.GetFirst(); wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
wxCHECK_RET( node, _T("no subitems at all??") ); wxCHECK_RET( node, _T("no subitems at all??") );
@ -2139,29 +2139,12 @@ void wxListMainWindow::Init()
m_freezeCount = 0; m_freezeCount = 0;
} }
void wxListMainWindow::InitScrolling()
{
if ( HasFlag(wxLC_REPORT) )
{
m_xScroll = SCROLL_UNIT_X;
m_yScroll = SCROLL_UNIT_Y;
}
else
{
m_xScroll = SCROLL_UNIT_Y;
m_yScroll = 0;
}
}
wxListMainWindow::wxListMainWindow() wxListMainWindow::wxListMainWindow()
{ {
Init(); Init();
m_highlightBrush = m_highlightBrush =
m_highlightUnfocusedBrush = (wxBrush *) NULL; m_highlightUnfocusedBrush = (wxBrush *) NULL;
m_xScroll =
m_yScroll = 0;
} }
wxListMainWindow::wxListMainWindow( wxWindow *parent, wxListMainWindow::wxListMainWindow( wxWindow *parent,
@ -2196,8 +2179,7 @@ wxListMainWindow::wxListMainWindow( wxWindow *parent,
wxSize sz = size; wxSize sz = size;
sz.y = 25; sz.y = 25;
InitScrolling(); SetScrollbars( SCROLL_UNIT_X, SCROLL_UNIT_Y, 0, 0, 0, 0 );
SetScrollbars( m_xScroll, m_yScroll, 0, 0, 0, 0 );
SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOX ) ); SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOX ) );
} }
@ -3048,8 +3030,8 @@ void wxListMainWindow::MoveToItem(size_t item)
int client_w, client_h; int client_w, client_h;
GetClientSize( &client_w, &client_h ); GetClientSize( &client_w, &client_h );
int view_x = m_xScroll*GetScrollPos( wxHORIZONTAL ); int view_x = SCROLL_UNIT_X*GetScrollPos( wxHORIZONTAL );
int view_y = m_yScroll*GetScrollPos( wxVERTICAL ); int view_y = SCROLL_UNIT_Y*GetScrollPos( wxVERTICAL );
if ( HasFlag(wxLC_REPORT) ) if ( HasFlag(wxLC_REPORT) )
{ {
@ -3058,16 +3040,16 @@ void wxListMainWindow::MoveToItem(size_t item)
ResetVisibleLinesRange(); ResetVisibleLinesRange();
if (rect.y < view_y ) if (rect.y < view_y )
Scroll( -1, rect.y/m_yScroll ); Scroll( -1, rect.y/SCROLL_UNIT_Y );
if (rect.y+rect.height+5 > view_y+client_h) if (rect.y+rect.height+5 > view_y+client_h)
Scroll( -1, (rect.y+rect.height-client_h+SCROLL_UNIT_Y)/m_yScroll ); Scroll( -1, (rect.y+rect.height-client_h+SCROLL_UNIT_Y)/SCROLL_UNIT_Y );
} }
else // !report else // !report
{ {
if (rect.x-view_x < 5) if (rect.x-view_x < 5)
Scroll( (rect.x-5)/m_xScroll, -1 ); Scroll( (rect.x-5)/SCROLL_UNIT_X, -1 );
if (rect.x+rect.width-5 > view_x+client_w) if (rect.x+rect.width-5 > view_x+client_w)
Scroll( (rect.x+rect.width-client_w+SCROLL_UNIT_X)/m_xScroll, -1 ); Scroll( (rect.x+rect.width-client_w+SCROLL_UNIT_X)/SCROLL_UNIT_X, -1 );
} }
} }
@ -3801,8 +3783,8 @@ wxRect wxListMainWindow::GetViewRect() const
} }
// some fudge needed to make it look prettier // some fudge needed to make it look prettier
xMax += EXTRA_WIDTH; xMax += 2*EXTRA_BORDER_X;
yMax += EXTRA_HEIGHT; yMax += 2*EXTRA_BORDER_Y;
// account for the scrollbars if necessary // account for the scrollbars if necessary
const wxSize sizeAll = GetClientSize(); const wxSize sizeAll = GetClientSize();
@ -3851,6 +3833,8 @@ void wxListMainWindow::RecalculatePositions(bool noRefresh)
wxClientDC dc( this ); wxClientDC dc( this );
dc.SetFont( GetFont() ); dc.SetFont( GetFont() );
const size_t count = GetItemCount();
int iconSpacing; int iconSpacing;
if ( HasFlag(wxLC_ICON) ) if ( HasFlag(wxLC_ICON) )
iconSpacing = m_normal_spacing; iconSpacing = m_normal_spacing;
@ -3881,104 +3865,146 @@ void wxListMainWindow::RecalculatePositions(bool noRefresh)
if ( HasFlag(wxLC_REPORT) ) if ( HasFlag(wxLC_REPORT) )
{ {
// all lines have the same height // all lines have the same height and we scroll one line per step
int lineHeight = GetLineHeight(); int lineHeight = GetLineHeight();
// scroll one line per step int entireHeight = count*lineHeight + LINE_SPACING;
m_yScroll = lineHeight;
size_t lineCount = GetItemCount();
int entireHeight = lineCount*lineHeight + LINE_SPACING;
m_linesPerPage = clientHeight / lineHeight; m_linesPerPage = clientHeight / lineHeight;
ResetVisibleLinesRange(); ResetVisibleLinesRange();
SetScrollbars( m_xScroll, m_yScroll, SetScrollbars( SCROLL_UNIT_X, lineHeight,
GetHeaderWidth() / m_xScroll, GetHeaderWidth() / SCROLL_UNIT_X,
(entireHeight + m_yScroll - 1)/m_yScroll, (entireHeight + lineHeight - 1) / lineHeight,
GetScrollPos(wxHORIZONTAL), GetScrollPos(wxHORIZONTAL),
GetScrollPos(wxVERTICAL), GetScrollPos(wxVERTICAL),
TRUE ); TRUE );
} }
else // !report else // !report
{ {
// at first we try without any scrollbar. if the items don't // we have 3 different layout strategies: either layout all items
// fit into the window, we recalculate after subtracting an // horizontally/vertically (wxLC_ALIGN_XXX styles explicitly given) or
// approximated 15 pt for the horizontal scrollbar // to arrange them in top to bottom, left to right (don't ask me why
// not the other way round...) order
int entireWidth = 0; if ( HasFlag(wxLC_ALIGN_LEFT | wxLC_ALIGN_TOP) )
for (int tries = 0; tries < 2; tries++)
{ {
// We start with 4 for the border around all items int x = EXTRA_BORDER_X;
entireWidth = 4; int y = EXTRA_BORDER_Y;
if (tries == 1) for ( size_t i = 0; i < count; i++ )
{ {
// Now we have decided that the items do not fit into the
// client area. Unfortunately, wxWindows sometimes thinks
// that it does fit and therefore NO horizontal scrollbar
// is inserted. This looks ugly, so we fudge here and make
// the calculated width bigger than was actually has been
// calculated. This ensures that wxScrolledWindows puts
// a scrollbar at the bottom of its client area.
entireWidth += SCROLL_UNIT_X;
}
// Start at 2,2 so the text does not touch the border
int x = 2;
int y = 2;
int maxWidth = 0;
m_linesPerPage = 0;
int currentlyVisibleLines = 0;
size_t count = GetItemCount();
for (size_t i = 0; i < count; i++)
{
currentlyVisibleLines++;
wxListLineData *line = GetLine(i); wxListLineData *line = GetLine(i);
line->CalculateSize( &dc, iconSpacing ); line->CalculateSize( &dc, iconSpacing );
line->SetPosition( x, y, clientWidth, iconSpacing ); // Why clientWidth? (FIXME) line->SetPosition( x, y, iconSpacing );
wxSize sizeLine = GetLineSize(i); wxSize sizeLine = GetLineSize(i);
if ( maxWidth < sizeLine.x ) if ( HasFlag(wxLC_ALIGN_TOP) )
maxWidth = sizeLine.x;
y += sizeLine.y;
if (currentlyVisibleLines > m_linesPerPage)
m_linesPerPage = currentlyVisibleLines;
// Assume that the size of the next one is the same... (FIXME)
if ( y + sizeLine.y >= clientHeight )
{ {
currentlyVisibleLines = 0; y += sizeLine.y;
y = 2;
x += maxWidth+6;
entireWidth += maxWidth+6;
maxWidth = 0;
} }
else // wxLC_ALIGN_LEFT
// We have reached the last item.
if ( i == count - 1 )
entireWidth += maxWidth;
if ( (tries == 0) && (entireWidth+SCROLL_UNIT_X > clientWidth) )
{ {
clientHeight -= 15; // We guess the scrollbar height. (FIXME) x += sizeLine.x + MARGIN_BETWEEN_ROWS;
m_linesPerPage = 0;
currentlyVisibleLines = 0;
break;
} }
if ( i == count - 1 )
tries = 1; // Everything fits, no second try required.
} }
}
int scroll_pos = GetScrollPos( wxHORIZONTAL ); SetScrollbars
SetScrollbars( m_xScroll, m_yScroll, (entireWidth+SCROLL_UNIT_X) / m_xScroll, 0, scroll_pos, 0, TRUE ); (
SCROLL_UNIT_X,
SCROLL_UNIT_Y,
(x + SCROLL_UNIT_X) / SCROLL_UNIT_X,
(y + SCROLL_UNIT_Y) / SCROLL_UNIT_Y,
GetScrollPos( wxHORIZONTAL ),
GetScrollPos( wxVERTICAL ),
TRUE
);
}
else // "flowed" arrangement, the most complicated case
{
// at first we try without any scrollbars, if the items don't fit into
// the window, we recalculate after subtracting the space taken by the
// scrollbar
int entireWidth = 0,
entireHeight = 0;
for (int tries = 0; tries < 2; tries++)
{
entireWidth = 2*EXTRA_BORDER_X;
entireHeight = 2*EXTRA_BORDER_Y;
if (tries == 1)
{
// Now we have decided that the items do not fit into the
// client area, so we need a scrollbar
entireWidth += SCROLL_UNIT_X;
}
int x = EXTRA_BORDER_X;
int y = EXTRA_BORDER_Y;
int maxWidthInThisRow = 0;
m_linesPerPage = 0;
int currentlyVisibleLines = 0;
for (size_t i = 0; i < count; i++)
{
currentlyVisibleLines++;
wxListLineData *line = GetLine(i);
line->CalculateSize( &dc, iconSpacing );
line->SetPosition( x, y, iconSpacing );
wxSize sizeLine = GetLineSize(i);
if ( maxWidthInThisRow < sizeLine.x )
maxWidthInThisRow = sizeLine.x;
y += sizeLine.y;
if (currentlyVisibleLines > m_linesPerPage)
m_linesPerPage = currentlyVisibleLines;
if ( y + sizeLine.y >= clientHeight )
{
currentlyVisibleLines = 0;
y = EXTRA_BORDER_Y;
maxWidthInThisRow += MARGIN_BETWEEN_ROWS;
x += maxWidthInThisRow;
entireWidth += maxWidthInThisRow;
maxWidthInThisRow = 0;
}
// We have reached the last item.
if ( i == count - 1 )
entireWidth += maxWidthInThisRow;
if ( (tries == 0) &&
(entireWidth + SCROLL_UNIT_X > clientWidth) )
{
clientHeight -= wxSystemSettings::
GetMetric(wxSYS_HSCROLL_Y);
m_linesPerPage = 0;
currentlyVisibleLines = 0;
break;
}
if ( i == count - 1 )
tries = 1; // Everything fits, no second try required.
}
}
SetScrollbars
(
SCROLL_UNIT_X,
SCROLL_UNIT_Y,
(entireWidth + SCROLL_UNIT_X) / SCROLL_UNIT_X,
0,
GetScrollPos( wxHORIZONTAL ),
0,
TRUE
);
}
} }
if ( !noRefresh ) if ( !noRefresh )