#if wxUSE_LISTCTRL
-// under Win32 we always use the native version and also may use the generic
-// one, however some things should be done only if we use only the generic
-// version
-#if (defined(__WIN32__) && !defined(__WXUNIVERSAL__)) || defined(__WXMAC__)
- #define HAVE_NATIVE_LISTCTRL
-#endif
-
-// if we have the native control, wx/listctrl.h declares it and not this one
#include "wx/listctrl.h"
-#ifndef HAVE_NATIVE_LISTCTRL
+#if (!defined(__WXMSW__) || defined(__WXUNIVERSAL__)) && !defined(__WXMAC__)
// if we have a native version, its implementation file does all this
IMPLEMENT_DYNAMIC_CLASS(wxListItem, wxObject)
IMPLEMENT_DYNAMIC_CLASS(wxListView, wxListCtrl)
IMPLEMENT_DYNAMIC_CLASS(wxListEvent, wxNotifyEvent)
IMPLEMENT_DYNAMIC_CLASS(wxListCtrl, wxGenericListCtrl)
-#endif // HAVE_NATIVE_LISTCTRL/!HAVE_NATIVE_LISTCTRL
+#endif
#ifndef WX_PRECOMP
+ #include "wx/scrolwin.h"
+ #include "wx/timer.h"
+ #include "wx/settings.h"
#include "wx/dynarray.h"
- #include "wx/app.h"
+ #include "wx/dcclient.h"
#include "wx/dcscreen.h"
- #include "wx/textctrl.h"
- #include "wx/listbox.h"
#include "wx/math.h"
#endif
+#include "wx/imaglist.h"
#include "wx/selstore.h"
#include "wx/renderer.h"
static const int LINE_SPACING = 0;
// extra margins around the text label
+#ifdef __WXGTK__
+static const int EXTRA_WIDTH = 6;
+#else
static const int EXTRA_WIDTH = 4;
+#endif
static const int EXTRA_HEIGHT = 4;
// margin between the window and the items
// wxListItemData (internal)
//-----------------------------------------------------------------------------
-class WXDLLEXPORT wxListItemData
+class wxListItemData
{
public:
wxListItemData(wxListMainWindow *owner);
// wxListHeaderData (internal)
//-----------------------------------------------------------------------------
-class WXDLLEXPORT wxListHeaderData : public wxObject
+class wxListHeaderData : public wxObject
{
public:
wxListHeaderData();
void SetItem( const wxListItem &item );
void SetPosition( int x, int y );
void SetWidth( int w );
+ void SetState( int state );
void SetFormat( int format );
void SetHeight( int h );
bool HasImage() const;
int GetImage() const;
int GetWidth() const;
int GetFormat() const;
+ int GetState() const;
protected:
long m_mask;
int m_xpos,
m_ypos;
int m_height;
+ int m_state;
private:
void Init();
// wxListHeaderWindow (internal)
//-----------------------------------------------------------------------------
-class WXDLLEXPORT wxListHeaderWindow : public wxWindow
+class wxListHeaderWindow : public wxWindow
{
protected:
wxListMainWindow *m_owner;
// wxListRenameTimer (internal)
//-----------------------------------------------------------------------------
-class WXDLLEXPORT wxListRenameTimer: public wxTimer
+class wxListRenameTimer: public wxTimer
{
private:
wxListMainWindow *m_owner;
// wxListTextCtrlWrapper: wraps a wxTextCtrl to make it work for inline editing
//-----------------------------------------------------------------------------
-class WXDLLEXPORT wxListTextCtrlWrapper : public wxEvtHandler
+class wxListTextCtrlWrapper : public wxEvtHandler
{
public:
// NB: text must be a valid object but not Create()d yet
// send out a wxListEvent
void SendNotify( size_t line,
- wxEventType command,
+ wxEventType command,
const wxPoint& point = wxDefaultPosition );
// override base class virtual to reset m_lineHeight when the font changes
{
return m_hasFocus ? m_highlightBrush : m_highlightUnfocusedBrush;
}
+
+ bool HasFocus() const
+ {
+ return m_hasFocus;
+ }
//protected:
// the array of all line objects for a non virtual list control (for the
if ( info.HasAttributes() )
{
if ( m_attr )
- *m_attr = *info.GetAttributes();
+ m_attr->AssignFrom(*info.GetAttributes());
else
m_attr = new wxListItemAttr(*info.GetAttributes());
}
m_xpos = 0;
m_ypos = 0;
m_height = 0;
+ m_state = 0;
}
wxListHeaderData::wxListHeaderData()
if ( m_mask & wxLIST_MASK_WIDTH )
SetWidth(item.m_width);
+
+ if ( m_mask & wxLIST_MASK_STATE )
+ SetState(item.m_state);
}
void wxListHeaderData::SetPosition( int x, int y )
m_width = w < 0 ? WIDTH_COL_DEFAULT : w;
}
+void wxListHeaderData::SetState( int flag )
+{
+ m_state = flag;
+}
+
void wxListHeaderData::SetFormat( int format )
{
m_format = format;
item.m_image = m_image;
item.m_format = m_format;
item.m_width = m_width;
+ item.m_state = m_state;
}
int wxListHeaderData::GetImage() const
return m_format;
}
+int wxListHeaderData::GetState() const
+{
+ return m_state;
+}
+
//-----------------------------------------------------------------------------
// wxListLineData
//-----------------------------------------------------------------------------
if ( item->HasText() )
{
if (m_gi->m_rectAll.width > spacing)
- m_gi->m_rectLabel.x = m_gi->m_rectAll.x + 2;
+ m_gi->m_rectLabel.x = m_gi->m_rectAll.x + (EXTRA_WIDTH/2);
else
- m_gi->m_rectLabel.x = m_gi->m_rectAll.x + 2 + (spacing / 2) - (m_gi->m_rectLabel.width / 2);
+ m_gi->m_rectLabel.x = m_gi->m_rectAll.x + (EXTRA_WIDTH/2) + (spacing / 2) - (m_gi->m_rectLabel.width / 2);
m_gi->m_rectLabel.y = m_gi->m_rectAll.y + m_gi->m_rectAll.height + 2 - m_gi->m_rectLabel.height;
m_gi->m_rectHighlight.x = m_gi->m_rectLabel.x - 2;
m_gi->m_rectHighlight.y = m_gi->m_rectLabel.y - 2;
{
m_gi->m_rectIcon.x = m_gi->m_rectAll.x + 2;
m_gi->m_rectIcon.y = m_gi->m_rectAll.y + 2;
- m_gi->m_rectLabel.x = m_gi->m_rectAll.x + 6 + m_gi->m_rectIcon.width;
+ m_gi->m_rectLabel.x = m_gi->m_rectAll.x + 4 + (EXTRA_WIDTH/2) + m_gi->m_rectIcon.width;
}
else
{
- m_gi->m_rectLabel.x = m_gi->m_rectAll.x + 2;
+ m_gi->m_rectLabel.x = m_gi->m_rectAll.x + (EXTRA_WIDTH/2);
}
break;
// arithmetics on wxColour, unfortunately)
wxColour colText;
if ( highlighted )
+#ifdef __WXMAC__
+ {
+ if (m_owner->HasFocus())
+ colText = *wxWHITE;
+ else
+ colText = *wxBLACK;
+ }
+#else
colText = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
+#endif
else if ( attr && attr->HasTextColour() )
colText = attr->GetTextColour();
else
wxListItemAttr *attr = GetAttr();
if ( SetAttributes(dc, attr, highlighted) )
+#if ( !defined(__WXGTK20__) && !defined(__WXMAC__) )
+ {
dc->DrawRectangle( m_gi->m_rectHighlight );
+ }
+#else
+ {
+ if (highlighted)
+ {
+ int flags = wxCONTROL_SELECTED;
+ if (m_owner->HasFocus())
+ flags |= wxCONTROL_FOCUSED;
+ wxRendererNative::Get().DrawItemSelectionRect( m_owner, *dc, m_gi->m_rectHighlight, flags );
+
+ }
+ else
+ {
+ dc->DrawRectangle( m_gi->m_rectHighlight );
+ }
+ }
+#endif
// just for debugging to better see where the items are
#if 0
// GetAttr() and move these lines into the loop below
wxListItemAttr *attr = GetAttr();
if ( SetAttributes(dc, attr, highlighted) )
+#if ( !defined(__WXGTK20__) && !defined(__WXMAC__) )
+ {
dc->DrawRectangle( rectHL );
+ }
+#else
+ {
+ if (highlighted)
+ {
+ int flags = wxCONTROL_SELECTED;
+ if (m_owner->HasFocus())
+ flags |= wxCONTROL_FOCUSED;
+ wxRendererNative::Get().DrawItemSelectionRect( m_owner, *dc, rectHL, flags );
+ }
+ else
+ {
+ dc->DrawRectangle( rectHL );
+ }
+ }
+#endif
wxCoord x = rect.x + HEADER_OFFSET_X,
yMid = rect.y + rect.height/2;
+#ifdef __WXGTK__
+ // This probably needs to be done
+ // on all platforms as the icons
+ // otherwise nearly touch the border
+ x += 2;
+#endif
size_t col = 0;
for ( wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
int ch = h - 2;
#endif
+ int flags = 0;
+ if (!m_parent->IsEnabled())
+ flags |= wxCONTROL_DISABLED;
+
+// NB: The code below is not really Mac-specific, but since we are close
+// to 2.8 release and I don't have time to test on other platforms, I
+// defined this only for wxMac. If this behavior is desired on
+// other platforms, please go ahead and revise or remove the #ifdef.
+#ifdef __WXMAC__
+ if ( !m_owner->IsVirtual() && (item.m_mask & wxLIST_MASK_STATE) &&
+ (item.m_state & wxLIST_STATE_SELECTED) )
+ flags |= wxCONTROL_SELECTED;
+#endif
+
wxRendererNative::Get().DrawHeaderButton
(
this,
dc,
wxRect(x, HEADER_OFFSET_Y, cw, ch),
- m_parent->IsEnabled() ? 0
- : (int)wxCONTROL_DISABLED
+ flags
);
// see if we have enough space for the column label
}
else // click on a column
{
+ // record the selected state of the columns
+ if (event.LeftDown())
+ {
+ for (int i=0; i < m_owner->GetColumnCount(); i++)
+ {
+ wxListItem colItem;
+ m_owner->GetColumn(i, colItem);
+ long state = colItem.GetState();
+ if (i == m_column)
+ colItem.SetState(state | wxLIST_STATE_SELECTED);
+ else
+ colItem.SetState(state & ~wxLIST_STATE_SELECTED);
+ m_owner->SetColumn(i, colItem);
+ }
+ }
+
SendListEvent( event.LeftDown()
? wxEVT_COMMAND_LIST_COL_CLICK
: wxEVT_COMMAND_LIST_COL_RIGHT_CLICK,
Init();
m_highlightBrush = new wxBrush
- (
+ (
wxSystemSettings::GetColour
(
wxSYS_COLOUR_HIGHLIGHT
),
wxSOLID
- );
-
+ );
+
m_highlightUnfocusedBrush = new wxBrush
- (
- wxSystemSettings::GetColour
- (
- wxSYS_COLOUR_BTNSHADOW
- ),
- wxSOLID
- );
+ (
+ wxSystemSettings::GetColour
+ (
+ wxSYS_COLOUR_BTNSHADOW
+ ),
+ wxSOLID
+ );
SetScrollbars( 0, 0, 0, 0, 0, 0 );
{
if ( m_hasFocus )
{
+ wxRect rect( GetLineHighlightRect( m_current ) );
+#ifndef __WXGTK20__
dc.SetPen( *wxBLACK_PEN );
dc.SetBrush( *wxTRANSPARENT_BRUSH );
- dc.DrawRectangle( GetLineHighlightRect( m_current ) );
+ dc.DrawRectangle( rect );
+#else
+ wxRendererNative::Get().DrawItemSelectionRect( this, dc, rect, wxCONTROL_CURRENT|wxCONTROL_FOCUSED );
+
+#endif
}
}
#endif
{
wxListEvent le( command, GetParent()->GetId() );
le.SetEventObject( GetParent() );
+
le.m_itemIndex = line;
// set only for events which have position
// program has it anyhow and if we did it would result in accessing all
// the lines, even those which are not visible now and this is precisely
// what we're trying to avoid
- if ( !IsVirtual() && (command != wxEVT_COMMAND_LIST_DELETE_ITEM) )
+ if ( !IsVirtual() )
{
if ( line != (size_t)-1 )
{
void wxListMainWindow::RecalculatePositions(bool noRefresh)
{
+ const int lineHeight = GetLineHeight();
+
wxClientDC dc( this );
dc.SetFont( GetFont() );
clientHeight;
GetSize( &clientWidth, &clientHeight );
- const int lineHeight = GetLineHeight();
-
if ( InReportView() )
{
// all lines have the same height and we scroll one line per step
if ( m_current != index || m_current == count - 1 )
m_current--;
}
-
+
if ( InReportView() )
{
- // mark the Column Max Width cache as dirty if the items in the line
- // we're deleting contain the Max Column Width
+ // mark the Column Max Width cache as dirty if the items in the line
+ // we're deleting contain the Max Column Width
wxListLineData * const line = GetLine(index);
wxListItemDataList::compatibility_iterator n;
wxListItemData *itemData;
ResetVisibleLinesRange();
}
+ SendNotify( index, wxEVT_COMMAND_LIST_DELETE_ITEM, wxDefaultPosition );
+
if ( IsVirtual() )
{
m_countVirt--;
// we need to refresh the (vert) scrollbar as the number of items changed
m_dirty = true;
- SendNotify( index, wxEVT_COMMAND_LIST_DELETE_ITEM );
-
RefreshAfter(index);
}
m_headerWin->Show( false );
}
- SetBestSize(size);
+ SetInitialSize(size);
return true;
}