// // the height of the header window (FIXME: should depend on its font!)
// static const int HEADER_HEIGHT = 23;
-// the scrollbar units
static const int SCROLL_UNIT_X = 15;
-static const int SCROLL_UNIT_Y = 15;
// the spacing between the lines (in report mode)
static const int LINE_SPACING = 0;
// extra margins around the text label
-static const int EXTRA_WIDTH = 3;
+static const int EXTRA_WIDTH = 4;
static const int EXTRA_HEIGHT = 4;
// margin between the window and the items
// do we have a header window?
bool HasHeader() const
- { return HasFlag(wxLC_REPORT) && !HasFlag(wxLC_NO_HEADER); }
+ { return InReportView() && !HasFlag(wxLC_NO_HEADER); }
void HighlightAll( bool on );
else // has label
{
dc->GetTextExtent( s, &lw, &lh );
- if (lh < SCROLL_UNIT_Y)
- lh = SCROLL_UNIT_Y;
lw += EXTRA_WIDTH;
lh += EXTRA_HEIGHT;
s = item->GetTextForMeasuring();
dc->GetTextExtent( s, &lw, &lh );
- if (lh < SCROLL_UNIT_Y)
- lh = SCROLL_UNIT_Y;
lw += EXTRA_WIDTH;
lh += EXTRA_HEIGHT;
bool wxListLineData::Highlight( bool on )
{
- wxCHECK_MSG( !m_owner->IsVirtual(), FALSE, _T("unexpected call to Highlight") );
+ wxCHECK_MSG( !IsVirtual(), FALSE, _T("unexpected call to Highlight") );
if ( on == m_highlighted )
return FALSE;
// for this we need the width of the text
wxCoord wLabel;
- dc.GetTextExtent(item.GetText(), &wLabel, NULL);
+ wxCoord hLabel;
+ dc.GetTextExtent(item.GetText(), &wLabel, &hLabel);
wLabel += 2*EXTRA_WIDTH;
// and the width of the icon, if any
wxDCClipper clipper(dc, x, HEADER_OFFSET_Y, cw, h - 4 );
dc.DrawText( item.GetText(),
- xAligned + EXTRA_WIDTH, HEADER_OFFSET_Y + EXTRA_HEIGHT );
+ xAligned + EXTRA_WIDTH, h / 2 - hLabel / 2 ); //HEADER_OFFSET_Y + EXTRA_HEIGHT );
x += wCol;
}
{
m_isDragging = TRUE;
m_currentX = x;
- DrawCurrent();
CaptureMouse();
+ DrawCurrent();
}
//else: column resizing was vetoed by the user code
}
void wxListHeaderWindow::OnSetFocus( wxFocusEvent &WXUNUSED(event) )
{
m_owner->SetFocus();
+ m_owner->Update();
}
bool wxListHeaderWindow::SendListEvent(wxEventType type, wxPoint pos)
{
// We must finish regardless of success, otherwise we'll get focus problems
Finish();
-
+
if ( !AcceptChanges() )
m_owner->OnRenameCancelled( m_itemEdited );
}
-
+
event.Skip();
}
wxSize sz = size;
sz.y = 25;
- SetScrollbars( SCROLL_UNIT_X, SCROLL_UNIT_Y, 0, 0, 0, 0 );
+ SetScrollbars( 0, 0, 0, 0, 0, 0 );
SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOX ) );
}
wxCoord wxListMainWindow::GetLineHeight() const
{
- wxASSERT_MSG( HasFlag(wxLC_REPORT), _T("only works in report mode") );
-
// we cache the line height as calling GetTextExtent() is slow
if ( !m_lineHeight )
{
wxCoord y;
dc.GetTextExtent(_T("H"), NULL, &y);
- if ( y < SCROLL_UNIT_Y )
- y = SCROLL_UNIT_Y;
-
if ( m_small_image_list && m_small_image_list->GetImageCount() )
{
int iw = 0;
wxCoord wxListMainWindow::GetLineY(size_t line) const
{
- wxASSERT_MSG( HasFlag(wxLC_REPORT), _T("only works in report mode") );
+ wxASSERT_MSG( InReportView(), _T("only works in report mode") );
return LINE_SPACING + line*GetLineHeight();
}
void wxListMainWindow::RefreshLine( size_t line )
{
- if ( HasFlag(wxLC_REPORT) )
+ if ( InReportView() )
{
size_t visibleFrom, visibleTo;
GetVisibleLinesRange(&visibleFrom, &visibleTo);
wxASSERT_MSG( lineTo < GetItemCount(), _T("invalid line range") );
- if ( HasFlag(wxLC_REPORT) )
+ if ( InReportView() )
{
size_t visibleFrom, visibleTo;
GetVisibleLinesRange(&visibleFrom, &visibleTo);
void wxListMainWindow::RefreshAfter( size_t lineFrom )
{
- if ( HasFlag(wxLC_REPORT) )
+ if ( InReportView() )
{
size_t visibleFrom, visibleTo;
GetVisibleLinesRange(&visibleFrom, &visibleTo);
dc.SetFont( GetFont() );
- if ( HasFlag(wxLC_REPORT) )
+ if ( InReportView() )
{
int lineHeight = GetLineHeight();
{
wxPen pen(GetRuleColour(), 1, wxSOLID);
- int col = 0;
wxRect firstItemRect;
wxRect lastItemRect;
GetItemRect(visibleFrom, firstItemRect);
int x = firstItemRect.GetX();
dc.SetPen(pen);
dc.SetBrush(* wxTRANSPARENT_BRUSH);
- for (col = 0; col < GetColumnCount(); col++)
+ for (int col = 0; col < GetColumnCount(); col++)
{
int colWidth = GetColumnWidth(col);
x += colWidth;
}
}
+#ifndef __WXMAC__
+ // Don't draw rect outline under Mac at all.
if ( HasCurrent() )
{
- // don't draw rect outline under Max if we already have the background
- // color but under other platforms only draw it if we do: it is a bit
- // silly to draw "focus rect" if we don't have focus!
-#ifdef __WXMAC__
- if ( !m_hasFocus )
-#else // !__WXMAC__
if ( m_hasFocus )
-#endif // __WXMAC__/!__WXMAC__
{
dc.SetPen( *wxBLACK_PEN );
dc.SetBrush( *wxTRANSPARENT_BRUSH );
dc.DrawRectangle( GetLineHighlightRect(m_current) );
}
}
+#endif
dc.EndDrawing();
}
le.IsAllowed();
}
-#ifdef __VMS__ // Ignore unreacheable code
-# pragma message disable initnotreach
-#endif
-
void wxListMainWindow::OnRenameCancelled(size_t itemEdit)
{
- // wxMSW seems not to notify the program about
- // cancelled label edits.
- return;
-
// let owner know that the edit was cancelled
wxListEvent le( wxEVT_COMMAND_LIST_END_LABEL_EDIT, GetParent()->GetId() );
-
- // These only exist for wxTreeCtrl, which should probably be changed
- // le.m_editCancelled = TRUE;
- // le.m_label = wxEmptyString;
-
+
+ le.SetEditCanceled(TRUE);
+
le.SetEventObject( GetParent() );
le.m_itemIndex = itemEdit;
GetEventHandler()->ProcessEvent( le );
}
-#ifdef __VMS__
-# pragma message enable initnotreach
-#endif
void wxListMainWindow::OnMouse( wxMouseEvent &event )
{
size_t count = GetItemCount(),
current;
- if ( HasFlag(wxLC_REPORT) )
+ if ( InReportView() )
{
current = y / GetLineHeight();
if ( current < count )
int client_w, client_h;
GetClientSize( &client_w, &client_h );
+ const int hLine = GetLineHeight();
+
int view_x = SCROLL_UNIT_X*GetScrollPos( wxHORIZONTAL );
- int view_y = SCROLL_UNIT_Y*GetScrollPos( wxVERTICAL );
+ int view_y = hLine*GetScrollPos( wxVERTICAL );
- if ( HasFlag(wxLC_REPORT) )
+ if ( InReportView() )
{
// the next we need the range of lines shown it might be different, so
// recalculate it
ResetVisibleLinesRange();
if (rect.y < view_y )
- Scroll( -1, rect.y/SCROLL_UNIT_Y );
+ Scroll( -1, rect.y/hLine );
if (rect.y+rect.height+5 > view_y+client_h)
- Scroll( -1, (rect.y+rect.height-client_h+SCROLL_UNIT_Y)/SCROLL_UNIT_Y );
+ Scroll( -1, (rect.y+rect.height-client_h+hLine)/hLine );
}
else // !report
{
{
ChangeCurrent(newCurrent);
+ // refresh the old focus to remove it
+ RefreshLine( oldCurrent );
+
// select all the items between the old and the new one
if ( oldCurrent > newCurrent )
{
HighlightAll(FALSE);
ChangeCurrent(newCurrent);
-
+
// refresh the old focus to remove it
RefreshLine( oldCurrent );
HighlightLine( m_current, TRUE );
}
}
-
+
RefreshLine( m_current );
MoveToFocus();
case WXK_PRIOR:
{
- int steps = 0;
- if ( HasFlag(wxLC_REPORT) )
- {
- steps = m_linesPerPage - 1;
- }
- else
- {
- steps = m_current % m_linesPerPage;
- }
+ int steps = InReportView() ? m_linesPerPage - 1 : m_current % m_linesPerPage;
int index = m_current - steps;
if (index < 0)
case WXK_NEXT:
{
- int steps = 0;
- if ( HasFlag(wxLC_REPORT) )
- {
- steps = m_linesPerPage - 1;
- }
- else
- {
- steps = m_linesPerPage - (m_current % m_linesPerPage) - 1;
- }
+ int steps = InReportView()
+ ? m_linesPerPage - 1
+ : m_linesPerPage - (m_current % m_linesPerPage) - 1;
size_t index = m_current + steps;
size_t count = GetItemCount();
break;
case WXK_LEFT:
- if ( !HasFlag(wxLC_REPORT) )
+ if ( !InReportView() )
{
int index = m_current - m_linesPerPage;
if (index < 0)
break;
case WXK_RIGHT:
- if ( !HasFlag(wxLC_REPORT) )
+ if ( !InReportView() )
{
size_t index = m_current + m_linesPerPage;
void wxListMainWindow::OnSetFocus( wxFocusEvent &WXUNUSED(event) )
{
+ if ( GetParent() )
+ {
+ wxFocusEvent event( wxEVT_SET_FOCUS, GetParent()->GetId() );
+ event.SetEventObject( GetParent() );
+ if ( GetParent()->GetEventHandler()->ProcessEvent( event) )
+ return;
+ }
+
// wxGTK sends us EVT_SET_FOCUS events even if we had never got
// EVT_KILL_FOCUS before which means that we finish by redrawing the items
// which are already drawn correctly resulting in horrible flicker - avoid
RefreshSelected();
}
-
- if ( !GetParent() )
- return;
-
- wxFocusEvent event( wxEVT_SET_FOCUS, GetParent()->GetId() );
- event.SetEventObject( GetParent() );
- GetParent()->GetEventHandler()->ProcessEvent( event );
}
void wxListMainWindow::OnKillFocus( wxFocusEvent &WXUNUSED(event) )
{
+ if ( GetParent() )
+ {
+ wxFocusEvent event( wxEVT_KILL_FOCUS, GetParent()->GetId() );
+ event.SetEventObject( GetParent() );
+ if ( GetParent()->GetEventHandler()->ProcessEvent( event) )
+ return;
+ }
m_hasFocus = FALSE;
-
RefreshSelected();
}
{
m_small_image_list->Draw( index, *dc, x, y, wxIMAGELIST_DRAW_TRANSPARENT );
}
- else if ( HasFlag(wxLC_REPORT) && (m_small_image_list))
+ else if ( InReportView() && (m_small_image_list))
{
m_small_image_list->Draw( index, *dc, x, y, wxIMAGELIST_DRAW_TRANSPARENT );
}
{
m_small_image_list->GetSize( index, width, height );
}
- else if ( HasFlag(wxLC_REPORT) && m_small_image_list )
+ else if ( InReportView() && m_small_image_list )
{
m_small_image_list->GetSize( index, width, height );
}
wxCHECK_RET( col >= 0 && col < GetColumnCount(),
_T("invalid column index") );
- wxCHECK_RET( HasFlag(wxLC_REPORT),
+ wxCHECK_RET( InReportView(),
_T("SetColumnWidth() can only be called in report mode.") );
m_dirty = TRUE;
clientHeight;
GetSize( &clientWidth, &clientHeight );
- if ( HasFlag(wxLC_REPORT) )
+ const int lineHeight = GetLineHeight();
+
+ if ( InReportView() )
{
// all lines have the same height and we scroll one line per step
- int lineHeight = GetLineHeight();
-
int entireHeight = count*lineHeight + LINE_SPACING;
m_linesPerPage = clientHeight / lineHeight;
SetScrollbars
(
SCROLL_UNIT_X,
- SCROLL_UNIT_Y,
+ lineHeight,
(x + SCROLL_UNIT_X) / SCROLL_UNIT_X,
- (y + SCROLL_UNIT_Y) / SCROLL_UNIT_Y,
+ (y + lineHeight) / lineHeight,
GetScrollPos( wxHORIZONTAL ),
GetScrollPos( wxVERTICAL ),
TRUE
// the window, we recalculate after subtracting the space taken by the
// scrollbar
- int entireWidth = 0,
- entireHeight = 0;
+ int entireWidth = 0;
for (int tries = 0; tries < 2; tries++)
{
entireWidth = 2*EXTRA_BORDER_X;
- entireHeight = 2*EXTRA_BORDER_Y;
if (tries == 1)
{
clientHeight -= wxSystemSettings::
GetMetric(wxSYS_HSCROLL_Y);
m_linesPerPage = 0;
- currentlyVisibleLines = 0;
break;
}
SetScrollbars
(
SCROLL_UNIT_X,
- SCROLL_UNIT_Y,
+ lineHeight,
(entireWidth + SCROLL_UNIT_X) / SCROLL_UNIT_X,
0,
GetScrollPos( wxHORIZONTAL ),
size_t count = GetItemCount();
- if ( HasFlag(wxLC_REPORT) )
+ if ( InReportView() )
{
size_t current = y / GetLineHeight();
if ( current < count )
m_dirty = TRUE;
+ #if 0
+ // this is unused variable
int mode = 0;
- if ( HasFlag(wxLC_REPORT) )
+ #endif
+ if ( InReportView() )
{
+ #if 0
+ // this is unused variable
mode = wxLC_REPORT;
+ #endif
ResetVisibleLinesRange();
}
else if ( HasFlag(wxLC_LIST) )
+ #if 0
+ // this is unused variable
mode = wxLC_LIST;
+ #else
+ {}
+ #endif
else if ( HasFlag(wxLC_ICON) )
+ #if 0
+ // this is unused variable
mode = wxLC_ICON;
+ #else
+ {}
+ #endif
else if ( HasFlag(wxLC_SMALL_ICON) )
+ #if 0
+ // this is unused variable
mode = wxLC_ICON; // no typo
+ #else
+ {}
+ #endif
else
{
wxFAIL_MSG( _T("unknown mode") );
m_dirty = TRUE;
+ // If an item is selected at or below the point of insertion, we need to
+ // increment the member variables because the current row's index has gone
+ // up by one
+ if ( HasCurrent() && m_current >= id )
+ {
+ m_current++;
+ }
+
SendNotify(id, wxEVT_COMMAND_LIST_INSERT_ITEM);
RefreshLines(id, GetItemCount() - 1);
void wxListMainWindow::InsertColumn( long col, wxListItem &item )
{
m_dirty = TRUE;
- if ( HasFlag(wxLC_REPORT) )
+ if ( InReportView() )
{
if (item.m_width == wxLIST_AUTOSIZE_USEHEADER)
item.m_width = GetTextLength( item.m_text );
void wxListMainWindow::GetVisibleLinesRange(size_t *from, size_t *to)
{
- wxASSERT_MSG( HasFlag(wxLC_REPORT), _T("this is for report mode only") );
+ wxASSERT_MSG( InReportView(), _T("this is for report mode only") );
if ( m_lineFrom == (size_t)-1 )
{
void wxGenericListCtrl::CalculateAndSetHeaderHeight()
{
- // we use the letter "H" for calculating the needed space, basing on the current font
- int w, h;
- m_headerWin->GetTextExtent(wxT("H"), &w, &h);
- m_headerHeight = h + 2 * HEADER_OFFSET_Y + EXTRA_HEIGHT;
- m_headerWin->SetSize(m_headerWin->GetSize().x, m_headerHeight);
+ if ( m_headerWin )
+ {
+ // we use 'g' to get the descent, too
+ int w, h, d;
+ m_headerWin->GetTextExtent(wxT("Hg"), &w, &h, &d);
+ h += d + 2 * HEADER_OFFSET_Y + EXTRA_HEIGHT;
+
+ // only update if changed
+ if ( h != m_headerHeight )
+ {
+ m_headerHeight = h;
+
+ m_headerWin->SetSize(m_headerWin->GetSize().x, m_headerHeight);
+
+ if ( HasHeader() )
+ ResizeReportView(TRUE);
+ }
+ }
}
void wxGenericListCtrl::CreateHeaderWindow()
m_mainWin = (wxListMainWindow*) NULL;
m_headerWin = (wxListHeaderWindow*) NULL;
+ m_headerHeight = 0;
+
if ( !(style & wxLC_MASK_TYPE) )
{
style = style | wxLC_LIST;
m_mainWin = new wxListMainWindow( this, -1, wxPoint(0,0), size, style );
- if ( HasFlag(wxLC_REPORT) )
+ if ( InReportView() )
{
CreateHeaderWindow();
m_mainWin->DeleteEverything();
// has the header visibility changed?
- bool hasHeader = HasFlag(wxLC_REPORT) && !HasFlag(wxLC_NO_HEADER),
- willHaveHeader = (flag & wxLC_REPORT) && !(flag & wxLC_NO_HEADER);
+ bool hasHeader = HasHeader();
+ bool willHaveHeader = (flag & wxLC_REPORT) && !(flag & wxLC_NO_HEADER);
if ( hasHeader != willHaveHeader )
{
void wxGenericListCtrl::OnInternalIdle()
{
wxWindow::OnInternalIdle();
-
+
// do it only if needed
if ( !m_mainWin->m_dirty )
return;
return -1;
}
-wxListItemAttr *wxGenericListCtrl::OnGetItemAttr(long item) const
+wxListItemAttr *
+wxGenericListCtrl::OnGetItemAttr(long WXUNUSED_UNLESS_DEBUG(item)) const
{
wxASSERT_MSG( item >= 0 && item < GetItemCount(),
_T("invalid item index in OnGetItemAttr()") );