#include "wx/generic/imaglist.h"
#include "wx/dynarray.h"
+#ifdef __WXGTK__
+#include <gtk/gtk.h>
+#include "wx/gtk/win_gtk.h"
+#endif
+
#ifndef wxUSE_GENERIC_LIST_EXTENSIONS
#define wxUSE_GENERIC_LIST_EXTENSIONS 1
#endif
+// ----------------------------------------------------------------------------
+// events
+// ----------------------------------------------------------------------------
+
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_DRAG)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_RDRAG)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_END_LABEL_EDIT)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_DELETE_ITEM)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_GET_INFO)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_SET_INFO)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_SELECTED)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_DESELECTED)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_KEY_DOWN)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_INSERT_ITEM)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_CLICK)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_ACTIVATED)
+
// ============================================================================
// private classes
// ============================================================================
const wxValidator& validator = wxDefaultValidator,
const wxString &name = "listctrltextctrl" );
void OnChar( wxKeyEvent &event );
+ void OnKeyUp( wxKeyEvent &event );
void OnKillFocus( wxFocusEvent &event );
private:
void RefreshLine( wxListLineData *line );
void OnPaint( wxPaintEvent &event );
void HilightAll( bool on );
- void SendNotify( wxListLineData *line, wxEventType command );
+ void SendNotify( wxListLineData *line,
+ wxEventType command,
+ wxPoint point = wxDefaultPosition );
void FocusLine( wxListLineData *line );
void UnfocusLine( wxListLineData *line );
void SelectLine( wxListLineData *line );
m_bound_all.width = 0;
m_bound_all.height = 0;
wxNode *node = m_items.First();
+ if (node)
+ {
+ wxListItemData *item = (wxListItemData*)node->Data();
+ if (item->HasImage())
+ {
+ int w = 0;
+ int h = 0;
+ m_owner->GetImageSize( item->GetImage(), w, h );
+ m_bound_icon.width = w;
+ m_bound_icon.height = h;
+ }
+ else
+ {
+ m_bound_icon.width = 0;
+ m_bound_icon.height = 0;
+ }
+ }
while (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
m_bound_all.height = lh;
node = node->Next();
}
+ m_bound_label.width = m_bound_all.width;
+ m_bound_label.height = m_bound_all.height;
break;
}
}
void wxListHeaderWindow::DoDrawRect( wxDC *dc, int x, int y, int w, int h )
{
+#ifdef __WXGTK__
+ GtkStateType state = GTK_STATE_NORMAL;
+ if (!m_parent->IsEnabled()) state = GTK_STATE_INSENSITIVE;
+
+ x = dc->XLOG2DEV( x );
+
+ gtk_paint_box (m_wxwindow->style, GTK_PIZZA(m_wxwindow)->bin_window, state, GTK_SHADOW_OUT,
+ (GdkRectangle*) NULL, m_wxwindow, "button", x-1, y-1, w+2, h+2);
+#else
const int m_corner = 1;
dc->SetBrush( *wxTRANSPARENT_BRUSH );
dc->DrawRectangle( x, y, 1, h ); // left (outer)
dc->DrawLine( x, y+h-1, x+1, y+h-1 );
dc->DrawLine( x+w-1, y, x+w-1, y+1 );
+#endif
}
// shift the DC origin to match the position of the main window horz
void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
{
+#ifdef __WXGTK__
+ wxClientDC dc( this );
+#else
wxPaintDC dc( this );
+#endif
+
PrepareDC( dc );
AdjustDC( dc );
BEGIN_EVENT_TABLE(wxListTextCtrl,wxTextCtrl)
EVT_CHAR (wxListTextCtrl::OnChar)
+ EVT_KEY_UP (wxListTextCtrl::OnKeyUp)
EVT_KILL_FOCUS (wxListTextCtrl::OnKillFocus)
END_EVENT_TABLE()
event.Skip();
}
+void wxListTextCtrl::OnKeyUp( wxKeyEvent &event )
+{
+ // auto-grow the textctrl:
+ wxSize parentSize = m_owner->GetSize();
+ wxPoint myPos = GetPosition();
+ wxSize mySize = GetSize();
+ int sx, sy;
+ GetTextExtent(GetValue() + _T("MM"), &sx, &sy);
+ if (myPos.x + sx > parentSize.x) sx = parentSize.x - myPos.x;
+ if (mySize.x > sx) sx = mySize.x;
+ SetSize(sx, -1);
+
+ event.Skip();
+}
+
void wxListTextCtrl::OnKillFocus( wxFocusEvent &WXUNUSED(event) )
{
if (!wxPendingDelete.Member(this))
wxPaintDC dc( this );
PrepareDC( dc );
+ int dev_x = 0;
+ int dev_y = 0;
+ CalcScrolledPosition( 0, 0, &dev_x, &dev_y );
+
if (m_dirty) return;
if (m_lines.GetCount() == 0) return;
if (m_mode & wxLC_REPORT)
{
wxPen pen(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DLIGHT), 1, wxSOLID);
- dc.SetPen(pen);
- dc.SetBrush(* wxTRANSPARENT_BRUSH);
-
wxSize clientSize = GetClientSize();
- wxRect itemRect;
int lineSpacing = 0;
wxListLineData *line = &m_lines[0];
m_lines[i].Draw( &dc );
// Draw horizontal rule if required
if (GetWindowStyle() & wxLC_HRULES)
- dc.DrawLine(0, i*lineSpacing, clientSize.x, i*lineSpacing);
+ {
+ dc.SetPen(pen);
+ dc.SetBrush(* wxTRANSPARENT_BRUSH);
+ dc.DrawLine(0 - dev_x , i*lineSpacing , clientSize.x - dev_x , i*lineSpacing );
+ }
}
// Draw last horizontal rule
if ((i > (size_t) (y_s / lineSpacing)) && (GetWindowStyle() & wxLC_HRULES))
- dc.DrawLine(0, i*lineSpacing, clientSize.x, i*lineSpacing);
+ {
+ dc.SetPen(pen);
+ dc.SetBrush(* wxTRANSPARENT_BRUSH);
+ dc.DrawLine(0 - dev_x , i*lineSpacing , clientSize.x - dev_x , i*lineSpacing );
+ }
// Draw vertical rules if required
if ((GetWindowStyle() & wxLC_VRULES) && (GetItemCount() > 0))
GetItemRect(0, firstItemRect);
GetItemRect(GetItemCount() - 1, lastItemRect);
int x = firstItemRect.GetX();
+ dc.SetPen(pen);
+ dc.SetBrush(* wxTRANSPARENT_BRUSH);
for (col = 0; col < GetColumnCount(); col++)
{
int colWidth = GetColumnWidth(col);
x += colWidth ;
- dc.DrawLine(x, firstItemRect.GetY() - 1, x, lastItemRect.GetBottom() + 1);
+ dc.DrawLine(x - dev_x, firstItemRect.GetY() - 1 - dev_y, x - dev_x, lastItemRect.GetBottom() + 1 - dev_y);
}
- }
+ }
}
else
{
}
}
-void wxListMainWindow::SendNotify( wxListLineData *line, wxEventType command )
+void wxListMainWindow::SendNotify( wxListLineData *line,
+ wxEventType command,
+ wxPoint point )
{
wxListEvent le( command, GetParent()->GetId() );
le.SetEventObject( GetParent() );
le.m_itemIndex = GetIndexOfLine( line );
+
+ // set only for events which have position
+ if ( point != wxDefaultPosition )
+ le.m_pointDrag = point;
+
line->GetItem( 0, le.m_item );
GetParent()->GetEventHandler()->ProcessEvent( le );
// GetParent()->GetEventHandler()->AddPendingEvent( le );
if (m_dragCount != 3) return;
- int command = wxEVT_COMMAND_LIST_BEGIN_DRAG;
- if (event.RightIsDown()) command = wxEVT_COMMAND_LIST_BEGIN_RDRAG;
+ int command = event.RightIsDown() ? wxEVT_COMMAND_LIST_BEGIN_RDRAG
+ : wxEVT_COMMAND_LIST_BEGIN_DRAG;
wxListEvent le( command, GetParent()->GetId() );
le.SetEventObject( GetParent() );
if (event.RightDown())
{
- SendNotify( line, wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK );
+ SendNotify( line, wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK,
+ event.GetPosition() );
return;
}
if (m_mode & wxLC_REPORT)
{
- if (item_y-5 < view_y )
- Scroll( -1, (item_y-5)/m_yScroll );
+ if (item_y < view_y )
+ Scroll( -1, (item_y)/m_yScroll );
if (item_y+item_h+5 > view_y+client_h)
Scroll( -1, (item_y+item_h-client_h+15)/m_yScroll );
}
if (item >= 0 && (size_t)item < m_lines.GetCount())
{
wxListLineData *line = &m_lines[(size_t)item];
- if (line->IsHilighted()) ret |= wxLIST_STATE_FOCUSED;
+ if (line->IsHilighted()) ret |= wxLIST_STATE_SELECTED;
}
}
return ret;
if (index >= 0 && (size_t)index < m_lines.GetCount())
{
m_lines[(size_t)index].GetRect( rect );
+ this->CalcScrolledPosition(rect.x,rect.y,&rect.x,&rect.y);
}
else
{
bool wxListMainWindow::GetItemPosition(long item, wxPoint& pos)
{
- if (item >= 0 && (size_t)item < m_lines.GetCount())
- {
- wxRect rect;
- m_lines[(size_t)item].GetRect( rect );
- pos.x = rect.x;
- pos.y = rect.y;
- }
- else
- {
- pos.x = 0;
- pos.y = 0;
- }
+ wxRect rect;
+ this->GetItemRect(item,rect);
+ pos.x=rect.x; pos.y=rect.y;
return TRUE;
}
if (m_mode & wxLC_REPORT)
{
+ // scroll one line per step
+ m_yScroll = lineSpacing;
+
int x = 4;
int y = 1;
int entireHeight = m_lines.GetCount() * lineSpacing + 2;
#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 );
+ SetScrollbars( m_xScroll, m_yScroll, 0, entireHeight/m_yScroll +1, 0, scroll_pos, TRUE );
#endif
GetClientSize( &clientWidth, &clientHeight );
#endif
y += lineSpacing; // one pixel blank line between items
}
- 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 );
+ SetScrollbars( m_xScroll, m_yScroll, entireWidth/m_xScroll +1, entireHeight/m_yScroll +1, x_scroll_pos , scroll_pos, TRUE );
#endif
}
else
{
wxListLineData *line = &m_lines[i];
long ret = line->IsHit( x, y );
- if (ret & flags)
+ if (ret) // & flags) // No: flags is output-only so may be garbage at this point
{
flags = (int)ret;
return count;
else
{
m_lines.Add( line );
- item.m_itemId = m_lines.GetCount();
+ item.m_itemId = m_lines.GetCount()-1;
}
}
void wxListMainWindow::OnScroll(wxScrollWinEvent& event)
{
- wxScrolledWindow::OnScroll( event ) ;
+ wxScrolledWindow::OnScroll( event ) ;
+
#if wxUSE_GENERIC_LIST_EXTENSIONS
if (event.GetOrientation() == wxHORIZONTAL && ( m_mode & wxLC_REPORT ))
m_imageListNormal = (wxImageList *) NULL;
m_imageListSmall = (wxImageList *) NULL;
m_imageListState = (wxImageList *) NULL;
+ m_ownsImageListNormal = m_ownsImageListSmall = m_ownsImageListState = FALSE;
m_mainWin = (wxListMainWindow*) NULL;
m_headerWin = (wxListHeaderWindow*) NULL;
}
wxListCtrl::~wxListCtrl()
{
+ if (m_ownsImageListNormal) delete m_imageListNormal;
+ if (m_ownsImageListSmall) delete m_imageListSmall;
+ if (m_ownsImageListState) delete m_imageListState;
}
bool wxListCtrl::Create(wxWindow *parent,
m_imageListNormal = (wxImageList *) NULL;
m_imageListSmall = (wxImageList *) NULL;
m_imageListState = (wxImageList *) NULL;
+ m_ownsImageListNormal = m_ownsImageListSmall = m_ownsImageListState = FALSE;
m_mainWin = (wxListMainWindow*) NULL;
m_headerWin = (wxListHeaderWindow*) NULL;
void wxListCtrl::SetImageList( wxImageList *imageList, int which )
{
+ if ( which == wxIMAGE_LIST_NORMAL )
+ {
+ if (m_ownsImageListNormal) delete m_imageListNormal;
+ m_imageListNormal = imageList;
+ m_ownsImageListNormal = FALSE;
+ }
+ else if ( which == wxIMAGE_LIST_SMALL )
+ {
+ if (m_ownsImageListSmall) delete m_imageListSmall;
+ m_imageListSmall = imageList;
+ m_ownsImageListSmall = FALSE;
+ }
+ else if ( which == wxIMAGE_LIST_STATE )
+ {
+ if (m_ownsImageListState) delete m_imageListState;
+ m_imageListState = imageList;
+ m_ownsImageListState = FALSE;
+ }
+
m_mainWin->SetImageList( imageList, which );
}
+void wxListCtrl::AssignImageList(wxImageList *imageList, int which)
+{
+ SetImageList(imageList, which);
+ if ( which == wxIMAGE_LIST_NORMAL )
+ m_ownsImageListNormal = TRUE;
+ else if ( which == wxIMAGE_LIST_SMALL )
+ m_ownsImageListSmall = TRUE;
+ else if ( which == wxIMAGE_LIST_STATE )
+ m_ownsImageListState = TRUE;
+}
+
bool wxListCtrl::Arrange( int WXUNUSED(flag) )
{
return 0;