/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
-#pragma implementation "listctrl.h"
+ #pragma implementation "listctrl.h"
+ #pragma implementation "listctrlbase.h"
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/listctrl.h"
#include "wx/generic/imaglist.h"
+#ifndef wxUSE_GENERIC_LIST_EXTENSIONS
+#define wxUSE_GENERIC_LIST_EXTENSIONS 1
+#endif
+
+// ============================================================================
+// private classes
+// ============================================================================
+
+//-----------------------------------------------------------------------------
+// wxListItemData (internal)
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxListItemData : public wxObject
+{
+public:
+ wxString m_text;
+ int m_image;
+ long m_data;
+ int m_xpos,m_ypos;
+ int m_width,m_height;
+
+ wxListItemAttr *m_attr;
+
+public:
+ wxListItemData();
+ ~wxListItemData() { delete m_attr; }
+
+ wxListItemData( const wxListItem &info );
+ void SetItem( const wxListItem &info );
+ void SetText( const wxString &s );
+ void SetImage( int image );
+ void SetData( long data );
+ void SetPosition( int x, int y );
+ void SetSize( int width, int height );
+ bool HasImage() const;
+ bool HasText() const;
+ bool IsHit( int x, int y ) const;
+ void GetText( wxString &s );
+ const wxString& GetText() { return m_text; }
+ int GetX( void ) const;
+ int GetY( void ) const;
+ int GetWidth() const;
+ int GetHeight() const;
+ int GetImage() const;
+ void GetItem( wxListItem &info ) const;
+
+ wxListItemAttr *GetAttributes() const { return m_attr; }
+
+private:
+ DECLARE_DYNAMIC_CLASS(wxListItemData);
+};
+
+//-----------------------------------------------------------------------------
+// wxListHeaderData (internal)
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxListHeaderData : public wxObject
+{
+protected:
+ long m_mask;
+ int m_image;
+ wxString m_text;
+ int m_format;
+ int m_width;
+ int m_xpos,m_ypos;
+ int m_height;
+
+public:
+ wxListHeaderData();
+ wxListHeaderData( const wxListItem &info );
+ void SetItem( const wxListItem &item );
+ void SetPosition( int x, int y );
+ void SetWidth( int w );
+ void SetFormat( int format );
+ void SetHeight( int h );
+ bool HasImage() const;
+ bool HasText() const;
+ bool IsHit( int x, int y ) const;
+ void GetItem( wxListItem &item );
+ void GetText( wxString &s );
+ int GetImage() const;
+ int GetWidth() const;
+ int GetFormat() const;
+
+private:
+ DECLARE_DYNAMIC_CLASS(wxListHeaderData);
+};
+
+//-----------------------------------------------------------------------------
+// wxListLineData (internal)
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxListLineData : public wxObject
+{
+public:
+ wxList m_items;
+ wxRect m_bound_all;
+ wxRect m_bound_label;
+ wxRect m_bound_icon;
+ wxRect m_bound_hilight;
+ int m_mode;
+ bool m_hilighted;
+ wxBrush *m_hilightBrush;
+ int m_spacing;
+ wxListMainWindow *m_owner;
+
+ void DoDraw( wxDC *dc, bool hilight, bool paintBG );
+
+public:
+ wxListLineData() {}
+ wxListLineData( wxListMainWindow *owner, int mode, wxBrush *hilightBrush );
+ void CalculateSize( wxDC *dc, int spacing );
+ void SetPosition( wxDC *dc, int x, int y, int window_width );
+ void SetColumnPosition( int index, int x );
+ void GetSize( int &width, int &height );
+ void GetExtent( int &x, int &y, int &width, int &height );
+ void GetLabelExtent( int &x, int &y, int &width, int &height );
+ long IsHit( int x, int y );
+ void InitItems( int num );
+ void SetItem( int index, const wxListItem &info );
+ void GetItem( int index, wxListItem &info );
+ void GetText( int index, wxString &s );
+ void SetText( int index, const wxString s );
+ int GetImage( int index );
+ void GetRect( wxRect &rect );
+ void Hilight( bool on );
+ void ReverseHilight();
+ void DrawRubberBand( wxDC *dc, bool on );
+ void Draw( wxDC *dc );
+ bool IsInRect( int x, int y, const wxRect &rect );
+ bool IsHilighted();
+ void AssignRect( wxRect &dest, int x, int y, int width, int height );
+ void AssignRect( wxRect &dest, const wxRect &source );
+
+private:
+ void SetAttributes(wxDC *dc,
+ const wxListItemAttr *attr,
+ const wxColour& colText, const wxFont& font,
+ bool hilight);
+
+ DECLARE_DYNAMIC_CLASS(wxListLineData);
+};
+
+//-----------------------------------------------------------------------------
+// wxListHeaderWindow (internal)
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxListHeaderWindow : public wxWindow
+{
+protected:
+ wxListMainWindow *m_owner;
+ wxCursor *m_currentCursor;
+ wxCursor *m_resizeCursor;
+ bool m_isDragging;
+ int m_column;
+ int m_minX;
+ int m_currentX;
+
+public:
+ wxListHeaderWindow();
+ ~wxListHeaderWindow();
+ wxListHeaderWindow( wxWindow *win, wxWindowID id, wxListMainWindow *owner,
+ const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize,
+ long style = 0, const wxString &name = "wxlistctrlcolumntitles" );
+ void DoDrawRect( wxDC *dc, int x, int y, int w, int h );
+ void OnPaint( wxPaintEvent &event );
+ void DrawCurrent();
+ void OnMouse( wxMouseEvent &event );
+ void OnSetFocus( wxFocusEvent &event );
+
+private:
+ DECLARE_DYNAMIC_CLASS(wxListHeaderWindow)
+ DECLARE_EVENT_TABLE()
+};
+
+//-----------------------------------------------------------------------------
+// wxListRenameTimer (internal)
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxListRenameTimer: public wxTimer
+{
+private:
+ wxListMainWindow *m_owner;
+
+public:
+ wxListRenameTimer( wxListMainWindow *owner );
+ void Notify();
+};
+
+//-----------------------------------------------------------------------------
+// wxListTextCtrl (internal)
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxListTextCtrl: public wxTextCtrl
+{
+private:
+ bool *m_accept;
+ wxString *m_res;
+ wxListMainWindow *m_owner;
+ wxString m_startValue;
+
+public:
+ wxListTextCtrl() {}
+ wxListTextCtrl( wxWindow *parent, const wxWindowID id,
+ bool *accept, wxString *res, wxListMainWindow *owner,
+ const wxString &value = "",
+ const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize,
+ int style = 0,
+ const wxValidator& validator = wxDefaultValidator,
+ const wxString &name = "listctrltextctrl" );
+ void OnChar( wxKeyEvent &event );
+ void OnKillFocus( wxFocusEvent &event );
+
+private:
+ DECLARE_DYNAMIC_CLASS(wxListTextCtrl);
+ DECLARE_EVENT_TABLE()
+};
+
+//-----------------------------------------------------------------------------
+// wxListMainWindow (internal)
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxListMainWindow: public wxScrolledWindow
+{
+public:
+ long m_mode;
+ wxList m_lines;
+ wxList m_columns;
+ wxListLineData *m_current;
+ wxListLineData *m_currentEdit;
+ int m_visibleLines;
+ wxBrush *m_hilightBrush;
+ wxColour *m_hilightColour;
+ int m_xScroll,m_yScroll;
+ bool m_dirty;
+ wxImageList *m_small_image_list;
+ wxImageList *m_normal_image_list;
+ int m_small_spacing;
+ int m_normal_spacing;
+ bool m_hasFocus;
+ bool m_usedKeys;
+ bool m_lastOnSame;
+ wxTimer *m_renameTimer;
+ bool m_renameAccept;
+ wxString m_renameRes;
+ bool m_isCreated;
+ int m_dragCount;
+ wxPoint m_dragStart;
+
+ // for double click logic
+ wxListLineData *m_lineLastClicked,
+ *m_lineBeforeLastClicked;
+
+public:
+ wxListMainWindow();
+ wxListMainWindow( wxWindow *parent, wxWindowID id,
+ const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize,
+ long style = 0, const wxString &name = "listctrlmainwindow" );
+ ~wxListMainWindow();
+ void RefreshLine( wxListLineData *line );
+ void OnPaint( wxPaintEvent &event );
+ void HilightAll( bool on );
+ void SendNotify( wxListLineData *line, wxEventType command );
+ void FocusLine( wxListLineData *line );
+ void UnfocusLine( wxListLineData *line );
+ void SelectLine( wxListLineData *line );
+ void DeselectLine( wxListLineData *line );
+ void DeleteLine( wxListLineData *line );
+
+ void EditLabel( long item );
+ void Edit( long item ) { EditLabel(item); } // deprecated
+ void OnRenameTimer();
+ void OnRenameAccept();
+
+ void OnMouse( wxMouseEvent &event );
+ void MoveToFocus();
+ void OnArrowChar( wxListLineData *newCurrent, bool shiftDown );
+ void OnChar( wxKeyEvent &event );
+ void OnKeyDown( wxKeyEvent &event );
+ void OnSetFocus( wxFocusEvent &event );
+ void OnKillFocus( wxFocusEvent &event );
+ void OnSize( wxSizeEvent &event );
+ void OnScroll(wxScrollWinEvent& event) ;
+
+ void DrawImage( int index, wxDC *dc, int x, int y );
+ void GetImageSize( int index, int &width, int &height );
+ int GetIndexOfLine( const wxListLineData *line );
+ int GetTextLength( wxString &s ); // should be const
+
+ void SetImageList( wxImageList *imageList, int which );
+ void SetItemSpacing( int spacing, bool isSmall = FALSE );
+ int GetItemSpacing( bool isSmall = FALSE );
+ void SetColumn( int col, wxListItem &item );
+ void SetColumnWidth( int col, int width );
+ void GetColumn( int col, wxListItem &item );
+ int GetColumnWidth( int vol );
+ int GetColumnCount();
+ int GetCountPerPage();
+ void SetItem( wxListItem &item );
+ void GetItem( wxListItem &item );
+ void SetItemState( long item, long state, long stateMask );
+ int GetItemState( long item, long stateMask );
+ int GetItemCount();
+ void GetItemRect( long index, wxRect &rect );
+ bool GetItemPosition( long item, wxPoint& pos );
+ int GetSelectedItemCount();
+ void SetMode( long mode );
+ long GetMode() const;
+ void CalculatePositions();
+ void RealizeChanges();
+ long GetNextItem( long item, int geometry, int state );
+ void DeleteItem( long index );
+ void DeleteAllItems();
+ void DeleteColumn( int col );
+ void DeleteEverything();
+ void EnsureVisible( long index );
+ long FindItem( long start, const wxString& str, bool partial = FALSE );
+ long FindItem( long start, long data);
+ long HitTest( int x, int y, int &flags );
+ void InsertItem( wxListItem &item );
+// void AddItem( wxListItem &item );
+ void InsertColumn( long col, wxListItem &item );
+// void AddColumn( wxListItem &item );
+ void SortItems( wxListCtrlCompare fn, long data );
+
+private:
+ DECLARE_DYNAMIC_CLASS(wxListMainWindow);
+ DECLARE_EVENT_TABLE()
+};
+
+// ============================================================================
+// implementation
+// ============================================================================
+
//-----------------------------------------------------------------------------
// wxListItemData
//-----------------------------------------------------------------------------
m_ypos = 0;
m_width = 0;
m_height = 0;
- m_colour = wxBLACK;
+ m_attr = NULL;
}
wxListItemData::wxListItemData( const wxListItem &info )
{
m_image = -1;
m_data = 0;
- m_colour = info.m_colour;
+ m_attr = NULL;
+
SetItem( info );
}
if (info.m_mask & wxLIST_MASK_TEXT) m_text = info.m_text;
if (info.m_mask & wxLIST_MASK_IMAGE) m_image = info.m_image;
if (info.m_mask & wxLIST_MASK_DATA) m_data = info.m_data;
- m_colour = info.m_colour;
+
+ if ( info.HasAttributes() )
+ {
+ if ( m_attr )
+ *m_attr = *info.GetAttributes();
+ else
+ m_attr = new wxListItemAttr(*info.GetAttributes());
+ }
+
m_xpos = 0;
m_ypos = 0;
m_width = info.m_width;
if (height != -1) m_height = height;
}
-void wxListItemData::SetColour( wxColour *col )
-{
- m_colour = col;
-}
-
bool wxListItemData::HasImage() const
{
return (m_image >= 0);
return m_image;
}
-void wxListItemData::GetItem( wxListItem &info )
+void wxListItemData::GetItem( wxListItem &info ) const
{
info.m_text = m_text;
info.m_image = m_image;
info.m_data = m_data;
- info.m_colour = m_colour;
-}
-wxColour *wxListItemData::GetColour()
-{
- return m_colour;
+ if ( m_attr )
+ {
+ if ( m_attr->HasTextColour() )
+ info.SetTextColour(m_attr->GetTextColour());
+ if ( m_attr->HasBackgroundColour() )
+ info.SetBackgroundColour(m_attr->GetBackgroundColour());
+ if ( m_attr->HasFont() )
+ info.SetFont(m_attr->GetFont());
+ }
}
//-----------------------------------------------------------------------------
case wxLC_ICON:
{
m_bound_all.width = m_spacing;
- m_bound_all.height = m_spacing+13;
wxNode *node = m_items.First();
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
- wxString s;
- item->GetText( s );
- long lw,lh;
+ wxString s = item->GetText();
+ if (s.IsEmpty()) s = wxT("H");
+ wxCoord lw,lh;
dc->GetTextExtent( s, &lw, &lh );
+ if (lh < 15) lh = 15;
+ lw += 4;
+ lh += 3;
+
+ m_bound_all.height = m_spacing+lh;
if (lw > m_spacing) m_bound_all.width = lw;
+ m_bound_label.width = lw;
+ m_bound_label.height = lh;
+
+ if (item->HasImage())
+ {
+ int w = 0;
+ int h = 0;
+ m_owner->GetImageSize( item->GetImage(), w, h );
+ m_bound_icon.width = w + 8;
+ m_bound_icon.height = h + 8;
+ }
+
+ if (!item->HasText())
+ {
+ m_bound_hilight.width = m_bound_icon.width;
+ m_bound_hilight.height = m_bound_icon.height;
+ }
+ else
+ {
+ m_bound_hilight.width = m_bound_label.width;
+ m_bound_hilight.height = m_bound_label.height;
+ }
}
break;
}
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
- wxString s;
- item->GetText( s );
- long lw,lh;
+
+ wxString s = item->GetText();
+ if (s.IsEmpty()) s = wxT("H");
+ wxCoord lw,lh;
dc->GetTextExtent( s, &lw, &lh );
+ if (lh < 15) lh = 15;
+ lw += 4;
+ lh += 3;
+ m_bound_label.width = lw;
+ m_bound_label.height = lh;
+
m_bound_all.width = lw;
m_bound_all.height = lh;
+
if (item->HasImage())
{
int w = 0;
int h = 0;
m_owner->GetImageSize( item->GetImage(), w, h );
- m_bound_all.width += 4 + w;
- if (h > m_bound_all.height) m_bound_all.height = h;
- }
+ m_bound_icon.width = w;
+ m_bound_icon.height = h;
+
+ m_bound_all.width += 4 + w;
+ if (h > m_bound_all.height) m_bound_all.height = h;
+ }
+
+ m_bound_hilight.width = m_bound_all.width;
+ m_bound_hilight.height = m_bound_all.height;
}
break;
}
while (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
- wxString s;
- item->GetText( s );
- if (s.IsNull()) s = "H";
- long lh;
- dc->GetTextExtent( s, (long*) NULL, &lh );
+ wxString s = item->GetText();
+ if (s.IsEmpty()) s = wxT("H");
+ wxCoord lw,lh;
+ dc->GetTextExtent( s, &lw, &lh );
+ if (lh < 15) lh = 15;
+ lw += 4;
+ lh += 3;
+
item->SetSize( item->GetWidth(), lh );
+ m_bound_all.width += lw;
m_bound_all.height = lh;
node = node->Next();
}
{
case wxLC_ICON:
{
- AssignRect( m_bound_icon, 0, 0, 0, 0 );
- AssignRect( m_bound_label, 0, 0, 0, 0 );
- AssignRect( m_bound_hilight, m_bound_all );
wxNode *node = m_items.First();
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
if (item->HasImage())
{
- wxListItemData *item = (wxListItemData*)node->Data();
- int w = 0;
- int h = 0;
- m_owner->GetImageSize( item->GetImage(), w, h );
- m_bound_icon.x = m_bound_all.x + (m_spacing/2) - (w/2);
- m_bound_icon.y = m_bound_all.y + m_spacing - h - 5;
- m_bound_icon.width = w;
- m_bound_icon.height = h;
- if (!item->HasText())
- {
- AssignRect( m_bound_hilight, m_bound_icon );
- m_bound_hilight.x -= 5;
- m_bound_hilight.y -= 5;
- m_bound_hilight.width += 9;
- m_bound_hilight.height += 9;
- }
+ m_bound_icon.x = m_bound_all.x + 4 + (m_spacing/2) - (m_bound_icon.width/2);
+ m_bound_icon.y = m_bound_all.y + 4;
}
if (item->HasText())
{
- wxString s;
- item->GetText( s );
- long lw,lh;
- dc->GetTextExtent( s, &lw, &lh );
if (m_bound_all.width > m_spacing)
- m_bound_label.x = m_bound_all.x;
+ m_bound_label.x = m_bound_all.x + 2;
else
- m_bound_label.x = m_bound_all.x + (m_spacing/2) - lw/2;
- m_bound_label.y = m_bound_all.y + m_bound_all.height - lh;
- m_bound_label.width = lw;
- m_bound_label.height = lh;
- AssignRect( m_bound_hilight, m_bound_label );
- m_bound_hilight.x -= 2;
- m_bound_hilight.y -= 2;
- m_bound_hilight.width += 4;
- m_bound_hilight.height += 4;
+ m_bound_label.x = m_bound_all.x + 2 + (m_spacing/2) - (m_bound_label.width/2);
+ m_bound_label.y = m_bound_all.y + m_bound_all.height + 2 - m_bound_label.height;
+ m_bound_hilight.x = m_bound_label.x - 2;
+ m_bound_hilight.y = m_bound_label.y - 2;
+ }
+ else
+ {
+ m_bound_hilight.x = m_bound_icon.x - 4;
+ m_bound_hilight.y = m_bound_icon.y - 4;
}
}
break;
}
case wxLC_LIST:
{
- AssignRect( m_bound_label, m_bound_all );
- m_bound_all.x -= 2;
- m_bound_all.y -= 2;
- m_bound_all.width += 4;
- m_bound_all.height += 3;
- AssignRect( m_bound_hilight, m_bound_all );
- AssignRect( m_bound_icon, 0, 0, 0, 0 );
+ m_bound_hilight.x = m_bound_all.x;
+ m_bound_hilight.y = m_bound_all.y;
+ m_bound_label.y = m_bound_all.y + 2;
wxNode *node = m_items.First();
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
if (item->HasImage())
- {
+ {
m_bound_icon.x = m_bound_all.x + 2;
m_bound_icon.y = m_bound_all.y + 2;
- int w;
- int h;
- m_owner->GetImageSize( item->GetImage(), w, h );
- m_bound_icon.width = w;
- m_bound_icon.height = h;
- m_bound_label.x += 4 + w;
- m_bound_label.width -= 4 + w;
- }
- }
+ m_bound_label.x = m_bound_all.x + 6 + m_bound_icon.width;
+ }
+ else
+ {
+ m_bound_label.x = m_bound_all.x + 2;
+ }
+ }
break;
}
case wxLC_REPORT:
{
- long lw,lh;
- dc->GetTextExtent( "H", &lw, &lh );
m_bound_all.x = 0;
- m_bound_all.y -= 0;
- m_bound_all.height = lh+3;
m_bound_all.width = window_width;
AssignRect( m_bound_hilight, m_bound_all );
- AssignRect( m_bound_label, m_bound_all );
- AssignRect( m_bound_icon, 0, 0, 0, 0 );
+ m_bound_label.x = m_bound_all.x + 2;
+ m_bound_label.y = m_bound_all.y + 2;
wxNode *node = m_items.First();
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
- wxString s;
- item->GetText( s );
- if (s.IsEmpty()) s = wxT("H");
- long lw,lh;
- dc->GetTextExtent( s, &lw, &lh );
- m_bound_label.width = lw;
- m_bound_label.height = lh;
- if (item->HasImage())
- {
+ if (item->HasImage())
+ {
m_bound_icon.x = m_bound_all.x + 2;
m_bound_icon.y = m_bound_all.y + 2;
- int w;
- int h;
- m_owner->GetImageSize( item->GetImage(), w, h );
- m_bound_icon.width = w;
- m_bound_icon.height = h;
- m_bound_label.x += 4 + w;
- }
- }
+ m_bound_label.x += 4 + m_bound_icon.width;
+ }
+ }
break;
}
}
void wxListLineData::SetColumnPosition( int index, int x )
{
- int i = index;
- wxNode *node = m_items.Nth( i );
+ wxNode *node = m_items.Nth( (size_t)index );
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
return -1;
}
+void wxListLineData::SetAttributes(wxDC *dc,
+ const wxListItemAttr *attr,
+ const wxColour& colText,
+ const wxFont& font,
+ bool hilight)
+{
+ // don't use foregroud colour for drawing highlighted items - this might
+ // make them completely invisible (and there is no way to do bit
+ // arithmetics on wxColour, unfortunately)
+ if ( !hilight && attr && attr->HasTextColour() )
+ {
+ dc->SetTextForeground(attr->GetTextColour());
+ }
+ else
+ {
+ dc->SetTextForeground(colText);
+ }
+
+ if ( attr && attr->HasFont() )
+ {
+ dc->SetFont(attr->GetFont());
+ }
+ else
+ {
+ dc->SetFont(font);
+ }
+}
+
void wxListLineData::DoDraw( wxDC *dc, bool hilight, bool paintBG )
{
- long dev_x = dc->LogicalToDeviceX( m_bound_all.x-2 );
- long dev_y = dc->LogicalToDeviceY( m_bound_all.y-2 );
- long dev_w = dc->LogicalToDeviceXRel( m_bound_all.width+4 );
- long dev_h = dc->LogicalToDeviceYRel( m_bound_all.height+4 );
+ int dev_x = 0;
+ int dev_y = 0;
+ m_owner->CalcScrolledPosition( m_bound_all.x, m_bound_all.y, &dev_x, &dev_y );
+ wxCoord dev_w = m_bound_all.width;
+ wxCoord dev_h = m_bound_all.height;
if (!m_owner->IsExposed( dev_x, dev_y, dev_w, dev_h ))
- {
return;
+
+ wxWindow *listctrl = m_owner->GetParent();
+
+ // default foreground colour
+ wxColour colText;
+ if ( hilight )
+ {
+ colText = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT );
+ }
+ else
+ {
+ colText = listctrl->GetForegroundColour();
}
- if (paintBG)
+ // default font
+ wxFont font = listctrl->GetFont();
+
+ // VZ: currently we set the colours/fonts only once, but like this (i.e.
+ // using SetAttributes() inside the loop), it will be trivial to
+ // customize the subitems (in report mode) too.
+ wxListItemData *item = (wxListItemData*)m_items.First()->Data();
+ wxListItemAttr *attr = item->GetAttributes();
+ SetAttributes(dc, attr, colText, font, hilight);
+
+ bool hasBgCol = attr && attr->HasBackgroundColour();
+ if ( paintBG || hasBgCol )
{
if (hilight)
{
dc->SetBrush( * m_hilightBrush );
- dc->SetPen( * wxTRANSPARENT_PEN );
}
else
{
- dc->SetBrush( * wxWHITE_BRUSH );
- dc->SetPen( * wxTRANSPARENT_PEN );
+ if ( hasBgCol )
+ dc->SetBrush(wxBrush(attr->GetBackgroundColour(), wxSOLID));
+ else
+ dc->SetBrush( * wxWHITE_BRUSH );
}
+
+ dc->SetPen( * wxTRANSPARENT_PEN );
dc->DrawRectangle( m_bound_hilight.x, m_bound_hilight.y,
m_bound_hilight.width, m_bound_hilight.height );
}
- dc->SetBackgroundMode(wxTRANSPARENT);
if (m_mode == wxLC_REPORT)
{
- wxString s;
wxNode *node = m_items.First();
while (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
- dc->SetClippingRegion( item->GetX(), item->GetY(), item->GetWidth()-3, item->GetHeight() );
int x = item->GetX();
if (item->HasImage())
{
m_owner->GetImageSize( item->GetImage(), x, y );
x += item->GetX() + 5;
}
+ dc->SetClippingRegion( item->GetX(), item->GetY(), item->GetWidth()-3, item->GetHeight() );
if (item->HasText())
{
- item->GetText( s );
- if (hilight)
- dc->SetTextForeground( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT ) );
- else
- dc->SetTextForeground( *item->GetColour() );
- dc->DrawText( s, x, item->GetY() );
+ dc->DrawText( item->GetText(), x, item->GetY()+1 );
}
dc->DestroyClippingRegion();
node = node->Next();
}
if (item->HasText())
{
- wxString s;
- item->GetText( s );
- if (hilight)
- dc->SetTextForeground( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT ) );
- else
- dc->SetTextForeground( * item->GetColour() );
- dc->DrawText( s, m_bound_label.x, m_bound_label.y );
+ dc->DrawText( item->GetText(), m_bound_label.x, m_bound_label.y );
}
}
}
void wxListLineData::Hilight( bool on )
{
if (on == m_hilighted) return;
+ m_hilighted = on;
if (on)
m_owner->SelectLine( this );
else
m_owner->DeselectLine( this );
- m_hilighted = on;
}
void wxListLineData::ReverseHilight( void )
{
wxPaintDC dc( this );
PrepareDC( dc );
+#if wxUSE_GENERIC_LIST_EXTENSIONS
+ if ( m_owner->GetMode() & wxLC_REPORT )
+ {
+ int x , y ;
+ int xpix , ypix ;
+ m_owner->GetScrollPixelsPerUnit( &xpix , &ypix ) ;
+ m_owner->ViewStart( &x, &y ) ;
+ dc.SetDeviceOrigin( -x * xpix, 0 );
+ }
+#endif
dc.BeginDrawing();
dc.SetFont( GetFont() );
dc.SetBackgroundMode(wxTRANSPARENT);
dc.SetTextForeground( *wxBLACK );
- if (m_foregroundColour.Ok()) dc.SetTextForeground( m_foregroundColour );
+
+ // do *not* use the listctrl colour for headers - one day we will have a
+ // function to set it separately
x = 1;
y = 1;
{
m_owner->GetColumn( i, item );
int cw = item.m_width-2;
- if ((i+1 == numColumns) || (x+item.m_width > w-5)) cw = w-x-1;
+#if wxUSE_GENERIC_LIST_EXTENSIONS
+ if ((i+1 == numColumns) || ( dc.LogicalToDeviceX(x+item.m_width) > w-5))
+ cw = dc.DeviceToLogicalX(w)-x-1;
+#else
+ if ((i+1 == numColumns) || (x+item.m_width > w-5))
+ cw = w-x-1;
+#endif
dc.SetPen( *wxWHITE_PEN );
DoDrawRect( &dc, x, y, cw, h-2 );
dc.DrawText( item.m_text, x+4, y+3 );
dc.DestroyClippingRegion();
x += item.m_width;
+#if wxUSE_GENERIC_LIST_EXTENSIONS
+ if (dc.LogicalToDeviceX(x) > w+5) break;
+#else
if (x > w+5) break;
+#endif
}
dc.EndDrawing();
}
void wxListHeaderWindow::OnMouse( wxMouseEvent &event )
{
- int x = event.GetX();
- int y = event.GetY();
+ wxCoord x = (wxCoord)event.GetX();
+ wxCoord y = (wxCoord)event.GetY();
if (m_isDragging)
{
DrawCurrent();
{
xpos += m_owner->GetColumnWidth( j );
m_column = j;
- if ((abs(x-xpos) < 3) && (y < 22))
+ if ((abs(x-xpos) < 3) && (y < 22) && (m_column < m_owner->GetColumnCount()-1))
{
hit_border = TRUE;
break;
}
- if (x-xpos < 0)
- {
- break;
- }
+ if (x-xpos < 0)
+ {
+ break;
+ }
m_minX = xpos;
}
if (event.LeftDown())
{
if (hit_border)
- {
+ {
m_isDragging = TRUE;
m_currentX = x;
DrawCurrent();
CaptureMouse();
return;
- }
- else
- {
+ }
+ else
+ {
wxListEvent le( wxEVT_COMMAND_LIST_COL_CLICK, GetParent()->GetId() );
le.SetEventObject( GetParent() );
- le.m_col = m_column;
+ le.m_col = m_column;
GetParent()->GetEventHandler()->ProcessEvent( le );
- return;
- }
+ return;
+ }
}
if (event.Moving())
EVT_KILL_FOCUS (wxListTextCtrl::OnKillFocus)
END_EVENT_TABLE()
-wxListTextCtrl::wxListTextCtrl( wxWindow *parent, const wxWindowID id,
- bool *accept, wxString *res, wxListMainWindow *owner,
- const wxString &value, const wxPoint &pos, const wxSize &size,
- int style, const wxValidator& validator, const wxString &name ) :
- wxTextCtrl( parent, id, value, pos, size, style, validator, name )
+wxListTextCtrl::wxListTextCtrl( wxWindow *parent,
+ const wxWindowID id,
+ bool *accept,
+ wxString *res,
+ wxListMainWindow *owner,
+ const wxString &value,
+ const wxPoint &pos,
+ const wxSize &size,
+ int style,
+ const wxValidator& validator,
+ const wxString &name )
+ : wxTextCtrl( parent, id, value, pos, size, style, validator, name )
{
m_res = res;
m_accept = accept;
{
(*m_accept) = TRUE;
(*m_res) = GetValue();
- m_owner->SetFocus();
+
+ if (!wxPendingDelete.Member(this))
+ wxPendingDelete.Append(this);
+
+ if ((*m_accept) && ((*m_res) != m_startValue))
+ m_owner->OnRenameAccept();
+
return;
}
if (event.m_keyCode == WXK_ESCAPE)
{
(*m_accept) = FALSE;
(*m_res) = "";
- m_owner->SetFocus();
+
+ if (!wxPendingDelete.Member(this))
+ wxPendingDelete.Append(this);
+
return;
}
+
event.Skip();
}
void wxListTextCtrl::OnKillFocus( wxFocusEvent &WXUNUSED(event) )
{
- if (wxPendingDelete.Member(this)) return;
-
- wxPendingDelete.Append(this);
+ if (!wxPendingDelete.Member(this))
+ wxPendingDelete.Append(this);
if ((*m_accept) && ((*m_res) != m_startValue))
m_owner->OnRenameAccept();
EVT_KEY_DOWN (wxListMainWindow::OnKeyDown)
EVT_SET_FOCUS (wxListMainWindow::OnSetFocus)
EVT_KILL_FOCUS (wxListMainWindow::OnKillFocus)
+ EVT_SCROLLWIN (wxListMainWindow::OnScroll)
END_EVENT_TABLE()
wxListMainWindow::wxListMainWindow()
m_renameTimer = new wxListRenameTimer( this );
m_isCreated = FALSE;
m_dragCount = 0;
+
+ m_lineLastClicked =
+ m_lineBeforeLastClicked = (wxListLineData *)NULL;
}
wxListMainWindow::wxListMainWindow( wxWindow *parent, wxWindowID id,
if (m_mode & wxLC_REPORT)
{
+#if wxUSE_GENERIC_LIST_EXTENSIONS
+ m_xScroll = 15;
+#else
m_xScroll = 0;
+#endif
m_yScroll = 15;
}
else
m_renameTimer = new wxListRenameTimer( this );
m_renameAccept = FALSE;
- SetBackgroundColour( *wxWHITE );
+ SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_LISTBOX ) );
}
wxListMainWindow::~wxListMainWindow()
{
+ DeleteEverything();
+
if (m_hilightBrush) delete m_hilightBrush;
delete m_renameTimer;
void wxListMainWindow::RefreshLine( wxListLineData *line )
{
+ if (m_dirty) return;
+
+ if (!line) return;
+
int x = 0;
int y = 0;
int w = 0;
int h = 0;
- if (line)
- {
- wxClientDC dc(this);
- PrepareDC( dc );
- line->GetExtent( x, y, w, h );
- wxRect rect(
- dc.LogicalToDeviceX(x-3),
- dc.LogicalToDeviceY(y-3),
- dc.LogicalToDeviceXRel(w+6),
- dc.LogicalToDeviceXRel(h+6) );
- Refresh( TRUE, &rect );
- }
+ line->GetExtent( x, y, w, h );
+ CalcScrolledPosition( x, y, &x, &y );
+ wxRect rect( x, y, w, h );
+ Refresh( TRUE, &rect );
}
void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
int dummy = 0;
line->GetSize( dummy, lineSpacing );
lineSpacing += 1;
-
+
int y_s = m_yScroll*GetScrollPos( wxVERTICAL );
-
+
wxNode *node = m_lines.Nth( y_s / lineSpacing );
- for (int i = 0; i < m_visibleLines+2; i++)
- {
- if (!node) break;
-
+ for (int i = 0; i < m_visibleLines+2; i++)
+ {
+ if (!node) break;
+
line = (wxListLineData*)node->Data();
line->Draw( &dc );
node = node->Next();
- }
+ }
}
else
{
le.m_itemIndex = GetIndexOfLine( line );
line->GetItem( 0, le.m_item );
GetParent()->GetEventHandler()->ProcessEvent( le );
+// GetParent()->GetEventHandler()->AddPendingEvent( le );
}
void wxListMainWindow::FocusLine( wxListLineData *WXUNUSED(line) )
void wxListMainWindow::EditLabel( long item )
{
- wxNode *node = m_lines.Nth( item );
+ wxNode *node = m_lines.Nth( (size_t)item );
wxCHECK_RET( node, wxT("wrong index in wxListCtrl::Edit()") );
m_currentEdit = (wxListLineData*) node->Data();
info.m_mask = wxLIST_MASK_TEXT;
info.m_itemId = le.m_itemIndex;
info.m_text = m_renameRes;
- info.m_colour = le.m_item.m_colour;
+ info.SetTextColour(le.m_item.GetTextColour());
SetItem( info );
}
wxClientDC dc(this);
PrepareDC(dc);
- long x = dc.DeviceToLogicalX( (long)event.GetX() );
- long y = dc.DeviceToLogicalY( (long)event.GetY() );
+ wxCoord x = dc.DeviceToLogicalX( (wxCoord)event.GetX() );
+ wxCoord y = dc.DeviceToLogicalY( (wxCoord)event.GetY() );
/* Did we actually hit an item ? */
long hitResult = 0;
if (event.Dragging())
{
if (m_dragCount == 0)
- m_dragStart = wxPoint(x,y);
-
+ m_dragStart = wxPoint(x,y);
+
m_dragCount++;
-
- if (m_dragCount != 3) return;
-
- int command = wxEVT_COMMAND_LIST_BEGIN_DRAG;
- if (event.RightIsDown()) command = wxEVT_COMMAND_LIST_BEGIN_RDRAG;
-
+
+ if (m_dragCount != 3) return;
+
+ int command = wxEVT_COMMAND_LIST_BEGIN_DRAG;
+ if (event.RightIsDown()) command = wxEVT_COMMAND_LIST_BEGIN_RDRAG;
+
wxListEvent le( command, GetParent()->GetId() );
le.SetEventObject( GetParent() );
- le.m_pointDrag = m_dragStart;
- GetParent()->GetEventHandler()->ProcessEvent( le );
-
- return;
+ le.m_pointDrag = m_dragStart;
+ GetParent()->GetEventHandler()->ProcessEvent( le );
+
+ return;
}
else
{
if (!line) return;
+ bool forceClick = FALSE;
if (event.ButtonDClick())
{
- m_usedKeys = FALSE;
- m_lastOnSame = FALSE;
m_renameTimer->Stop();
+ m_lastOnSame = FALSE;
+
+ if ( line == m_lineBeforeLastClicked )
+ {
+ m_usedKeys = FALSE;
- SendNotify( line, wxEVT_COMMAND_LIST_ITEM_ACTIVATED );
+ SendNotify( line, wxEVT_COMMAND_LIST_ITEM_ACTIVATED );
- return;
+ return;
+ }
+ else
+ {
+ // the first click was on another item, so don't interpret this as
+ // a double click, but as a simple click instead
+ forceClick = TRUE;
+ }
}
if (event.LeftUp() && m_lastOnSame)
return;
}
- if (event.LeftDown())
+ if ( event.LeftDown() || forceClick )
{
+ m_lineBeforeLastClicked = m_lineLastClicked;
+ m_lineLastClicked = line;
+
m_usedKeys = FALSE;
wxListLineData *oldCurrent = m_current;
if (m_mode & wxLC_SINGLE_SEL)
}
else
{
- if (event.ShiftDown())
+ if (event.ControlDown())
{
m_current = line;
m_current->ReverseHilight();
RefreshLine( m_current );
}
- else if (event.ControlDown())
+ else if (event.ShiftDown())
{
m_current = line;
-
+
int numOfCurrent = -1;
node = m_lines.First();
while (node)
if (test_line == oldCurrent) break;
node = node->Next();
}
-
+
int numOfLine = -1;
node = m_lines.First();
while (node)
if (numOfLine < numOfCurrent)
{
- int i = numOfLine;
- numOfLine = numOfCurrent;
- numOfCurrent = i;
- }
-
+ int i = numOfLine;
+ numOfLine = numOfCurrent;
+ numOfCurrent = i;
+ }
+
wxNode *node = m_lines.Nth( numOfCurrent );
for (int i = 0; i <= numOfLine-numOfCurrent; i++)
{
UnfocusLine( oldCurrent );
FocusLine( m_current );
}
- m_lastOnSame = (m_current == oldCurrent);
+
+ // forceClick is only set if the previous click was on another item
+ m_lastOnSame = !forceClick && (m_current == oldCurrent);
+
return;
}
}
{
if (!m_current) return;
- int x = 0;
- int y = 0;
- int w = 0;
- int h = 0;
- m_current->GetExtent( x, y, w, h );
+ int item_x = 0;
+ int item_y = 0;
+ int item_w = 0;
+ int item_h = 0;
+ m_current->GetExtent( item_x, item_y, item_w, item_h );
- int w_p = 0;
- int h_p = 0;
- GetClientSize( &w_p, &h_p );
+ int client_w = 0;
+ int client_h = 0;
+ GetClientSize( &client_w, &client_h );
+
+ int view_x = m_xScroll*GetScrollPos( wxHORIZONTAL );
+ int view_y = m_yScroll*GetScrollPos( wxVERTICAL );
if (m_mode & wxLC_REPORT)
{
- int y_s = m_yScroll*GetScrollPos( wxVERTICAL );
- if ((y > y_s) && (y+h < y_s+h_p)) return;
- if (y-y_s < 5) { Scroll( -1, (y-5-h_p/2)/m_yScroll ); }
- if (y+h+5 > y_s+h_p) { Scroll( -1, (y+h-h_p/2+h+15)/m_yScroll); }
+ if (item_y-5 < view_y )
+ Scroll( -1, (item_y-5)/m_yScroll );
+ if (item_y+item_h+5 > view_y+client_h)
+ Scroll( -1, (item_y+item_h-client_h+15)/m_yScroll );
}
else
{
- int x_s = m_xScroll*GetScrollPos( wxHORIZONTAL );
- if ((x > x_s) && (x+w < x_s+w_p)) return;
- if (x-x_s < 5) { Scroll( (x-5)/m_xScroll, -1 ); }
- if (x+w-5 > x_s+w_p) { Scroll( (x+w-w_p+15)/m_xScroll, -1 ); }
+ if (item_x-view_x < 5)
+ Scroll( (item_x-5)/m_xScroll, -1 );
+ if (item_x+item_w-5 > view_x+client_w)
+ Scroll( (item_x+item_w-client_w+15)/m_xScroll, -1 );
}
}
if ((m_mode & wxLC_SINGLE_SEL) || (m_usedKeys == FALSE)) m_current->Hilight( FALSE );
wxListLineData *oldCurrent = m_current;
m_current = newCurrent;
- MoveToFocus();
if (shiftDown || (m_mode & wxLC_SINGLE_SEL)) m_current->Hilight( TRUE );
RefreshLine( m_current );
RefreshLine( oldCurrent );
FocusLine( m_current );
UnfocusLine( oldCurrent );
+ MoveToFocus();
}
void wxListMainWindow::OnKeyDown( wxKeyEvent &event )
/* we send a list_key event up */
wxListEvent le( wxEVT_COMMAND_LIST_KEY_DOWN, GetParent()->GetId() );
- le.m_code = event.KeyCode();
+ le.m_code = (int)event.KeyCode();
le.SetEventObject( parent );
parent->GetEventHandler()->ProcessEvent( le );
if (event.KeyCode() == WXK_TAB)
{
wxNavigationKeyEvent nevent;
+ nevent.SetWindowChange( event.ControlDown() );
nevent.SetDirection( !event.ShiftDown() );
+ nevent.SetEventObject( GetParent()->GetParent() );
nevent.SetCurrentFocus( m_parent );
- if (m_parent->GetEventHandler()->ProcessEvent( nevent )) return;
+ if (GetParent()->GetParent()->GetEventHandler()->ProcessEvent( nevent )) return;
}
/* no item -> nothing to do */
{
int steps = 0;
if (m_mode & wxLC_REPORT)
- {
- steps = m_visibleLines-1;
- }
+ {
+ steps = m_visibleLines-1;
+ }
else
{
int pos = 0;
{
int steps = 0;
if (m_mode & wxLC_REPORT)
- {
- steps = m_visibleLines-1;
- }
+ {
+ steps = m_visibleLines-1;
+ }
else
{
int pos = 0; wxNode *node = m_lines.First();
}
case WXK_SPACE:
{
- m_current->ReverseHilight();
- RefreshLine( m_current );
+ if (m_mode & wxLC_SINGLE_SEL)
+ {
+ wxListEvent le( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, GetParent()->GetId() );
+ le.SetEventObject( GetParent() );
+ le.m_itemIndex = GetIndexOfLine( m_current );
+ m_current->GetItem( 0, le.m_item );
+ GetParent()->GetEventHandler()->ProcessEvent( le );
+ }
+ else
+ {
+ m_current->ReverseHilight();
+ RefreshLine( m_current );
+ }
break;
}
case WXK_INSERT:
m_current->ReverseHilight();
wxNode *node = m_lines.Member( m_current )->Next();
if (node) m_current = (wxListLineData*)node->Data();
- MoveToFocus();
RefreshLine( oldCurrent );
RefreshLine( m_current );
UnfocusLine( oldCurrent );
FocusLine( m_current );
+ MoveToFocus();
}
break;
}
We don't even allow the wxScrolledWindow::AdjustScrollbars() call
*/
+ m_dirty = TRUE;
}
void wxListMainWindow::DrawImage( int index, wxDC *dc, int x, int y )
int wxListMainWindow::GetTextLength( wxString &s )
{
wxClientDC dc( this );
- long lw = 0;
- long lh = 0;
+ wxCoord lw = 0;
+ wxCoord lh = 0;
dc.GetTextExtent( s, &lw, &lh );
return lw + 6;
}
if (n)
{
wxListItemData *item = (wxListItemData*)n->Data();
- int current = 0, ix = 0, iy = 0;
- long lx = 0, ly = 0;
- if (item->HasImage())
- {
+ int current = 0, ix = 0, iy = 0;
+ wxCoord lx = 0, ly = 0;
+ if (item->HasImage())
+ {
GetImageSize( item->GetImage(), ix, iy );
- current = ix + 5;
- }
- if (item->HasText())
- {
- wxString str;
- item->GetText( str );
- dc.GetTextExtent( str, &lx, &ly );
- current += lx;
- }
- if (current > max) max = current;
+ current = ix + 5;
+ }
+ if (item->HasText())
+ {
+ wxString str;
+ item->GetText( str );
+ dc.GetTextExtent( str, &lx, &ly );
+ current += lx;
+ }
+ if (current > max) max = current;
}
node = node->Next();
}
- width = max+10;
+ width = max+10;
}
node = m_columns.Nth( col );
void wxListMainWindow::SetItem( wxListItem &item )
{
m_dirty = TRUE;
- wxNode *node = m_lines.Nth( item.m_itemId );
+ wxNode *node = m_lines.Nth( (size_t)item.m_itemId );
if (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
if (stateMask & wxLIST_STATE_FOCUSED)
{
- wxNode *node = m_lines.Nth( item );
+ wxNode *node = m_lines.Nth( (size_t)item );
if (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
if (stateMask & wxLIST_STATE_SELECTED)
{
- bool on = state & wxLIST_STATE_SELECTED;
+ bool on = (state & wxLIST_STATE_SELECTED) != 0;
if (!on && (m_mode & wxLC_SINGLE_SEL)) return;
- wxNode *node = m_lines.Nth( item );
+ wxNode *node = m_lines.Nth( (size_t)item );
if (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
RefreshLine( m_current );
if (oldCurrent) RefreshLine( oldCurrent );
}
- bool on = state & wxLIST_STATE_SELECTED;
- if (on != line->IsHilighted())
- {
+ bool on = (state & wxLIST_STATE_SELECTED) != 0;
+ if (on != line->IsHilighted())
+ {
line->Hilight( on );
RefreshLine( line );
- }
+ }
}
}
}
int ret = wxLIST_STATE_DONTCARE;
if (stateMask & wxLIST_STATE_FOCUSED)
{
- wxNode *node = m_lines.Nth( item );
+ wxNode *node = m_lines.Nth( (size_t)item );
if (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
}
if (stateMask & wxLIST_STATE_SELECTED)
{
- wxNode *node = m_lines.Nth( item );
+ wxNode *node = m_lines.Nth( (size_t)item );
if (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
void wxListMainWindow::GetItem( wxListItem &item )
{
- wxNode *node = m_lines.Nth( item.m_itemId );
+ wxNode *node = m_lines.Nth( (size_t)item.m_itemId );
if (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
void wxListMainWindow::GetItemRect( long index, wxRect &rect )
{
- wxNode *node = m_lines.Nth( index );
+ wxNode *node = m_lines.Nth( (size_t)index );
if (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
bool wxListMainWindow::GetItemPosition(long item, wxPoint& pos)
{
- wxNode *node = m_lines.Nth( item );
+ wxNode *node = m_lines.Nth( (size_t)item );
if (node)
{
wxRect rect;
if (m_mode & wxLC_REPORT)
{
+#if wxUSE_GENERIC_LIST_EXTENSIONS
+ m_xScroll = 15;
+#else
m_xScroll = 0;
+#endif
m_yScroll = 15;
}
else
line->CalculateSize( &dc, iconSpacing );
int dummy = 0;
line->GetSize( dummy, lineSpacing );
- lineSpacing += 4;
+ lineSpacing += 1;
int clientWidth = 0;
int clientHeight = 0;
int y = 1;
int entireHeight = m_lines.Number() * lineSpacing + 2;
int scroll_pos = GetScrollPos( wxVERTICAL );
+#if wxUSE_GENERIC_LIST_EXTENSIONS
+ int x_scroll_pos = GetScrollPos( wxHORIZONTAL );
+#else
SetScrollbars( m_xScroll, m_yScroll, 0, (entireHeight+15) / m_yScroll, 0, scroll_pos, TRUE );
+#endif
GetClientSize( &clientWidth, &clientHeight );
wxNode* node = m_lines.First();
+ int entireWidth = 0 ;
while (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
line->SetColumnPosition( i, col_x );
col_x += GetColumnWidth( i );
}
+ entireWidth = wxMax( entireWidth , col_x ) ;
+#if wxUSE_GENERIC_LIST_EXTENSIONS
+ line->SetPosition( &dc, x, y, col_x );
+#endif
y += lineSpacing; // one pixel blank line between items
node = node->Next();
}
- m_visibleLines = clientHeight / lineSpacing;
+ m_visibleLines = clientHeight / lineSpacing;
+#if wxUSE_GENERIC_LIST_EXTENSIONS
+ SetScrollbars( m_xScroll, m_yScroll, entireWidth / m_xScroll , (entireHeight+15) / m_yScroll, x_scroll_pos , scroll_pos, TRUE );
+#endif
}
else
{
// approximated 15 pt for the horizontal scrollbar
GetSize( &clientWidth, &clientHeight );
- clientHeight -= 4; // sunken frame
+ clientHeight -= 4; // sunken frame
int entireWidth = 0;
for (int tries = 0; tries < 2; tries++)
{
entireWidth = 0;
- int x = 5; // painting is done at x-2
- int y = 5; // painting is done at y-2
+ int x = 2;
+ int y = 2;
int maxWidth = 0;
m_visibleLines = 0;
- int m_currentVisibleLines = 0;
+ int m_currentVisibleLines = 0;
wxNode *node = m_lines.First();
while (node)
{
- m_currentVisibleLines++;
+ m_currentVisibleLines++;
wxListLineData *line = (wxListLineData*)node->Data();
line->CalculateSize( &dc, iconSpacing );
line->SetPosition( &dc, x, y, clientWidth );
line->GetSize( lineWidth, lineHeight );
if (lineWidth > maxWidth) maxWidth = lineWidth;
y += lineSpacing;
+ if (m_currentVisibleLines > m_visibleLines)
+ m_visibleLines = m_currentVisibleLines;
if (y+lineSpacing-6 >= clientHeight) // -6 for earlier "line breaking"
{
- if (m_currentVisibleLines > m_visibleLines)
- m_visibleLines = m_currentVisibleLines;
- m_currentVisibleLines = 0;
- y = 5;
+ m_currentVisibleLines = 0;
+ y = 2;
x += maxWidth+6;
entireWidth += maxWidth+6;
maxWidth = 0;
{
clientHeight -= 15; // scrollbar height
m_visibleLines = 0;
- m_currentVisibleLines = 0;
+ m_currentVisibleLines = 0;
break;
}
if (!node) tries = 1; // everything fits, no second try required
}
}
-// m_visibleLines = (5+clientHeight+6) / (lineSpacing); // +6 for earlier "line breaking"
-
+
int scroll_pos = GetScrollPos( wxHORIZONTAL );
SetScrollbars( m_xScroll, m_yScroll, (entireWidth+15) / m_xScroll, 0, scroll_pos, 0, TRUE );
}
}
}
-long wxListMainWindow::GetNextItem( long item, int WXUNUSED(geometry), int state )
+long wxListMainWindow::GetNextItem( long item,
+ int WXUNUSED(geometry),
+ int state )
{
- long ret = 0;
- if (item > 0) ret = item;
- if(ret >= GetItemCount()) return -1;
- wxNode *node = m_lines.Nth( ret );
+ long ret = item,
+ max = GetItemCount();
+ wxCHECK_MSG( (ret == -1) || (ret < max), -1,
+ _T("invalid listctrl index in GetNextItem()") );
+
+ // notice that we start with the next item (or the first one if item == -1)
+ // and this is intentional to allow writing a simple loop to iterate over
+ // all selected items
+ ret++;
+ if ( ret == max )
+ {
+ // this is not an error because the index was ok initially, just no
+ // such item
+ return -1;
+ }
+
+ wxNode *node = m_lines.Nth( (size_t)ret );
while (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
- if ((state & wxLIST_STATE_FOCUSED) && (line == m_current)) return ret;
- if ((state & wxLIST_STATE_SELECTED) && (line->IsHilighted())) return ret;
- if (!state) return ret;
+ if ((state & wxLIST_STATE_FOCUSED) && (line == m_current))
+ return ret;
+ if ((state & wxLIST_STATE_SELECTED) && (line->IsHilighted()))
+ return ret;
+ if (!state)
+ return ret;
ret++;
+
node = node->Next();
}
+
return -1;
}
void wxListMainWindow::DeleteItem( long index )
{
m_dirty = TRUE;
- wxNode *node = m_lines.Nth( index );
+ wxNode *node = m_lines.Nth( (size_t)index );
if (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
if (node) m_columns.DeleteNode( node );
}
-void wxListMainWindow::DeleteAllItems( void )
+void wxListMainWindow::DeleteAllItems()
{
m_dirty = TRUE;
m_current = (wxListLineData *) NULL;
- wxNode *node = m_lines.First();
- while (node)
- {
- wxListLineData *line = (wxListLineData*)node->Data();
- DeleteLine( line );
- node = node->Next();
- }
+
+ // to make the deletion of all items faster, we don't send the
+ // notifications in this case: this is compatible with wxMSW and
+ // documented in DeleteAllItems() description
+
+ wxListEvent event( wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS, GetParent()->GetId() );
+ event.SetEventObject( GetParent() );
+ GetParent()->GetEventHandler()->ProcessEvent( event );
+
m_lines.Clear();
}
-void wxListMainWindow::DeleteEverything( void )
+void wxListMainWindow::DeleteEverything()
{
- m_dirty = TRUE;
- m_current = (wxListLineData *) NULL;
- wxNode *node = m_lines.First();
- while (node)
- {
- wxListLineData *line = (wxListLineData*)node->Data();
- DeleteLine( line );
- node = node->Next();
- }
- m_lines.Clear();
- m_current = (wxListLineData *) NULL;
+ DeleteAllItems();
+
m_columns.Clear();
}
wxListLineData *oldCurrent = m_current;
m_current = (wxListLineData *) NULL;
- int i = index;
- wxNode *node = m_lines.Nth( i );
+ wxNode *node = m_lines.Nth( (size_t)index );
if (node) m_current = (wxListLineData*)node->Data();
if (m_current) MoveToFocus();
m_current = oldCurrent;
long pos = start;
wxString tmp = str;
if (pos < 0) pos = 0;
- wxNode *node = m_lines.Nth( pos );
+ wxNode *node = m_lines.Nth( (size_t)pos );
while (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
{
long pos = start;
if (pos < 0) pos = 0;
- wxNode *node = m_lines.Nth( pos );
+ wxNode *node = m_lines.Nth( (size_t)pos );
while (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
long ret = line->IsHit( x, y );
if (ret & flags)
{
- flags = ret;
+ flags = (int)ret;
return count;
}
node = node->Next();
line->SetItem( 0, item );
if ((item.m_itemId >= 0) && (item.m_itemId < (int)m_lines.GetCount()))
{
- wxNode *node = m_lines.Nth( item.m_itemId );
+ wxNode *node = m_lines.Nth( (size_t)item.m_itemId );
if (node) m_lines.Insert( node, line );
}
else
wxListHeaderData *column = new wxListHeaderData( item );
if ((col >= 0) && (col < (int)m_columns.GetCount()))
{
- wxNode *node = m_columns.Nth( col );
+ wxNode *node = m_columns.Nth( (size_t)col );
if (node)
m_columns.Insert( node, column );
}
list_ctrl_compare_func_2 = fn;
list_ctrl_compare_data = data;
m_lines.Sort( list_ctrl_compare_func_1 );
+ m_dirty = TRUE;
+}
+
+void wxListMainWindow::OnScroll(wxScrollWinEvent& event)
+{
+ wxScrolledWindow::OnScroll( event ) ;
+#if wxUSE_GENERIC_LIST_EXTENSIONS
+
+ if (event.GetOrientation() == wxHORIZONTAL && ( m_mode & wxLC_REPORT ))
+ {
+ wxListCtrl* lc = wxDynamicCast( GetParent() , wxListCtrl ) ;
+ if ( lc )
+ {
+ lc->m_headerWin->Refresh() ;
+#ifdef __WXMAC__
+ lc->m_headerWin->MacUpdateImmediately() ;
+#endif
+ }
+ }
+#endif
}
// -------------------------------------------------------------------------------------
m_data = 0;
m_format = wxLIST_FORMAT_CENTRE;
m_width = 0;
- m_colour = wxBLACK;
+
+ m_attr = NULL;
+}
+
+void wxListItem::Clear()
+{
+ m_mask = 0;
+ m_itemId = 0;
+ m_col = 0;
+ m_state = 0;
+ m_stateMask = 0;
+ m_image = 0;
+ m_data = 0;
+ m_format = wxLIST_FORMAT_CENTRE;
+ m_width = 0;
+ m_text = wxEmptyString;
+
+ if (m_attr) delete m_attr;
+ m_attr = NULL;
+}
+
+void wxListItem::ClearAttributes()
+{
+ if (m_attr) delete m_attr;
+ m_attr = NULL;
}
// -------------------------------------------------------------------------------------
m_pointDrag.y = 0;
}
+void wxListEvent::CopyObject(wxObject& object_dest) const
+{
+ wxListEvent *obj = (wxListEvent *)&object_dest;
+
+ wxNotifyEvent::CopyObject(object_dest);
+
+ obj->m_code = m_code;
+ obj->m_itemIndex = m_itemIndex;
+ obj->m_oldItemIndex = m_oldItemIndex;
+ obj->m_col = m_col;
+ obj->m_cancelled = m_cancelled;
+ obj->m_pointDrag = m_pointDrag;
+ obj->m_item.m_mask = m_item.m_mask;
+ obj->m_item.m_itemId = m_item.m_itemId;
+ obj->m_item.m_col = m_item.m_col;
+ obj->m_item.m_state = m_item.m_state;
+ obj->m_item.m_stateMask = m_item.m_stateMask;
+ obj->m_item.m_text = m_item.m_text;
+ obj->m_item.m_image = m_item.m_image;
+ obj->m_item.m_data = m_item.m_data;
+ obj->m_item.m_format = m_item.m_format;
+ obj->m_item.m_width = m_item.m_width;
+
+ if ( m_item.HasAttributes() )
+ {
+ obj->m_item.SetTextColour(m_item.GetTextColour());
+ }
+}
+
// -------------------------------------------------------------------------------------
// wxListCtrl
// -------------------------------------------------------------------------------------
{
}
-bool wxListCtrl::Create( wxWindow *parent, wxWindowID id,
- const wxPoint &pos, const wxSize &size,
- long style, const wxValidator &validator,
- const wxString &name )
+bool wxListCtrl::Create(wxWindow *parent,
+ wxWindowID id,
+ const wxPoint &pos,
+ const wxSize &size,
+ long style,
+ const wxValidator &validator,
+ const wxString &name)
{
m_imageListNormal = (wxImageList *) NULL;
m_imageListSmall = (wxImageList *) NULL;
m_mainWin = (wxListMainWindow*) NULL;
m_headerWin = (wxListHeaderWindow*) NULL;
- long s = style;
-
- if ((s & wxLC_REPORT == 0) &&
- (s & wxLC_LIST == 0) &&
- (s & wxLC_ICON == 0))
+ if ( !(style & (wxLC_REPORT | wxLC_LIST | wxLC_ICON)) )
{
- s = s | wxLC_LIST;
+ style = style | wxLC_LIST;
}
+
+ bool ret = wxControl::Create( parent, id, pos, size, style, validator, name );
+
+
+ if (style & wxSUNKEN_BORDER)
+ style -= wxSUNKEN_BORDER;
- bool ret = wxControl::Create( parent, id, pos, size, s, name );
-
-#if wxUSE_VALIDATORS
- SetValidator( validator );
-#endif
-
- if (s & wxSUNKEN_BORDER) s -= wxSUNKEN_BORDER;
-
- m_mainWin = new wxListMainWindow( this, -1, wxPoint(0,0), size, s );
+ m_mainWin = new wxListMainWindow( this, -1, wxPoint(0,0), size, style );
if (HasFlag(wxLC_REPORT))
+ {
m_headerWin = new wxListHeaderWindow( this, -1, m_mainWin, wxPoint(0,0), wxSize(size.x,23), wxTAB_TRAVERSAL );
+ if (HasFlag(wxLC_NO_HEADER))
+ m_headerWin->Show( FALSE );
+ }
else
+ {
m_headerWin = (wxListHeaderWindow *) NULL;
+ }
- SetBackgroundColour( *wxWHITE );
+ SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_LISTBOX ) );
return ret;
}
if (!m_headerWin)
{
m_headerWin = new wxListHeaderWindow( this, -1, m_mainWin,
- wxPoint(0,0), wxSize(width,23), wxTAB_TRAVERSAL );
- if (HasFlag(wxLC_NO_HEADER))
- m_headerWin->Show( FALSE );
+ wxPoint(0,0), wxSize(width,23), wxTAB_TRAVERSAL );
+ if (HasFlag(wxLC_NO_HEADER))
+ m_headerWin->Show( FALSE );
}
else
{
- if (flag & wxLC_NO_HEADER)
- m_headerWin->Show( FALSE );
- else
+ if (flag & wxLC_NO_HEADER)
+ m_headerWin->Show( FALSE );
+ else
m_headerWin->Show( TRUE );
}
}
{
m_headerWin->Show( FALSE );
}
- }
+ }
}
wxWindow::SetWindowStyleFlag( flag );
return m_mainWin->GetSelectedItemCount();
}
-/*
wxColour wxListCtrl::GetTextColour() const
{
+ return GetForegroundColour();
}
-void wxListCtrl::SetTextColour(const wxColour& WXUNUSED(col))
+void wxListCtrl::SetTextColour(const wxColour& col)
{
+ SetForegroundColour(col);
}
-*/
long wxListCtrl::GetTopItem() const
{
{
for ( size_t n = 0; n < m_mainWin->m_columns.GetCount(); n++ )
DeleteColumn(n);
-
+
return TRUE;
}
long wxListCtrl::InsertColumn( long col, wxListItem &item )
{
+ wxASSERT( m_headerWin );
m_mainWin->InsertColumn( col, item );
+ m_headerWin->Refresh();
+
return 0;
}
return TRUE;
}
+#if wxUSE_DRAG_AND_DROP
+
+void wxListCtrl::SetDropTarget( wxDropTarget *dropTarget )
+{
+ m_mainWin->SetDropTarget( dropTarget );
+}
+
+wxDropTarget *wxListCtrl::GetDropTarget() const
+{
+ return m_mainWin->GetDropTarget();
+}
+
+#endif // wxUSE_DRAG_AND_DROP
+
+bool wxListCtrl::SetCursor( const wxCursor &cursor )
+{
+ return m_mainWin ? m_mainWin->wxWindow::SetCursor(cursor) : FALSE;
+}
+
+wxColour wxListCtrl::GetBackgroundColour() const
+{
+ return m_mainWin ? m_mainWin->GetBackgroundColour() : wxColour();
+}
+
+wxColour wxListCtrl::GetForegroundColour() const
+{
+ return m_mainWin ? m_mainWin->GetForegroundColour() : wxColour();
+}
+
+bool wxListCtrl::DoPopupMenu( wxMenu *menu, int x, int y )
+{
+ return m_mainWin->PopupMenu( menu, x, y );
+}
+
+void wxListCtrl::SetFocus()
+{
+ /* The test in window.cpp fails as we are a composite
+ window, so it checks against "this", but not m_mainWin. */
+ if ( FindFocus() != this )
+ m_mainWin->SetFocus();
+}