#if wxUSE_LISTCTRL
-#include "wx/dcscreen.h"
-#include "wx/app.h"
-#include "wx/listctrl.h"
+#ifndef WX_PRECOMP
+ #include "wx/app.h"
+
+ #include "wx/dynarray.h"
+
+ #include "wx/dcscreen.h"
+
+ #include "wx/textctrl.h"
+#endif
+
#include "wx/imaglist.h"
-#include "wx/dynarray.h"
+#include "wx/listctrl.h"
#ifdef __WXGTK__
-#include <gtk/gtk.h>
-#include "wx/gtk/win_gtk.h"
+ #include <gtk/gtk.h>
+ #include "wx/gtk/win_gtk.h"
#endif
// ----------------------------------------------------------------------------
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)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_FOCUSED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_CACHE_HINT)
// ----------------------------------------------------------------------------
wxString *m_res;
wxListMainWindow *m_owner;
wxString m_startValue;
+ bool m_finished;
public:
wxListTextCtrl() {}
// bring the current item into view
void MoveToFocus() { MoveToItem(m_current); }
+ // start editing the label of the given item
void EditLabel( long item );
+
+ // suspend/resume redrawing the control
+ void Freeze();
+ void Thaw();
+
void OnRenameTimer();
void OnRenameAccept();
bool IsEmpty() const { return GetItemCount() == 0; }
void SetItemCount(long count);
- void ResetCurrent() { m_current = (size_t)-1; }
+ // change the current (== focused) item, send a notification event
+ void ChangeCurrent(size_t current);
+ void ResetCurrent() { ChangeCurrent((size_t)-1); }
bool HasCurrent() const { return m_current != (size_t)-1; }
// send out a wxListEvent
// delete all items but don't refresh: called from dtor
void DoDeleteAllItems();
- // called when an item is [un]focuded, i.e. becomes [not] current
- //
- // currently unused
- void OnFocusLine( size_t line );
- void OnUnfocusLine( size_t line );
-
// the height of one line using the current font
wxCoord m_lineHeight;
wxBrush *m_highlightBrush,
*m_highlightUnfocusedBrush;
+ // if this is > 0, the control is frozen and doesn't redraw itself
+ size_t m_freezeCount;
+
DECLARE_DYNAMIC_CLASS(wxListMainWindow);
DECLARE_EVENT_TABLE()
};
// stop counting (see comment below)
itemsChanged = NULL;
}
-
- itemsChanged->Add(m_itemsSel[i]);
+ else
+ {
+ itemsChanged->Add(m_itemsSel[i]);
+ }
}
m_itemsSel.RemoveAt(i);
int numColumns = m_owner->GetColumnCount();
wxListItem item;
- for (int i = 0; i < numColumns; i++)
+ for ( int i = 0; i < numColumns && x < w; i++ )
{
m_owner->GetColumn( i, item );
int wCol = item.m_width;
dc.DrawText( item.GetText(),
x + EXTRA_WIDTH, HEADER_OFFSET_Y + EXTRA_HEIGHT );
- if ( x > w - wCol + 5 )
- break;
-
x += wCol;
}
+
dc.EndDrawing();
}
(*m_accept) = FALSE;
(*m_res) = "";
m_startValue = value;
+ m_finished = FALSE;
}
void wxListTextCtrl::OnChar( wxKeyEvent &event )
if (!wxPendingDelete.Member(this))
wxPendingDelete.Append(this);
- if ((*m_accept) && ((*m_res) != m_startValue))
+ if ((*m_res) != m_startValue)
m_owner->OnRenameAccept();
+ m_finished = TRUE;
+ m_owner->SetFocus(); // This doesn't work. TODO.
+
return;
}
if (event.m_keyCode == WXK_ESCAPE)
if (!wxPendingDelete.Member(this))
wxPendingDelete.Append(this);
+ m_finished = TRUE;
+ m_owner->SetFocus(); // This doesn't work. TODO.
+
return;
}
void wxListTextCtrl::OnKeyUp( wxKeyEvent &event )
{
+ if (m_finished)
+ {
+ event.Skip();
+ return;
+ }
+
// auto-grow the textctrl:
wxSize parentSize = m_owner->GetSize();
wxPoint myPos = GetPosition();
wxSize mySize = GetSize();
int sx, sy;
- GetTextExtent(GetValue() + _T("MM"), &sx, &sy); // FIXME: MM??
+ GetTextExtent(GetValue() + _T("M"), &sx, &sy); // FIXME: MM??
if (myPos.x + sx > parentSize.x)
sx = parentSize.x - myPos.x;
if (mySize.x > sx)
event.Skip();
}
-void wxListTextCtrl::OnKillFocus( wxFocusEvent &WXUNUSED(event) )
+void wxListTextCtrl::OnKillFocus( wxFocusEvent &event )
{
+ if (m_finished)
+ {
+ event.Skip();
+ return;
+ }
+
if (!wxPendingDelete.Member(this))
wxPendingDelete.Append(this);
- if ((*m_accept) && ((*m_res) != m_startValue))
+ (*m_accept) = TRUE;
+ (*m_res) = GetValue();
+
+ if ((*m_res) != m_startValue)
m_owner->OnRenameAccept();
}
m_currentEdit =
m_lineLastClicked =
m_lineBeforeLastClicked = (size_t)-1;
+
+ m_freezeCount = 0;
}
void wxListMainWindow::InitScrolling()
#endif // !__WXGTK__/__WXGTK__
}
+void wxListMainWindow::Freeze()
+{
+ m_freezeCount++;
+}
+
+void wxListMainWindow::Thaw()
+{
+ wxCHECK_RET( m_freezeCount > 0, _T("thawing unfrozen list control?") );
+
+ if ( !--m_freezeCount )
+ {
+ Refresh();
+ }
+}
+
void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
{
// Note: a wxPaintDC must be constructed even if no drawing is
// done (a Windows requirement).
wxPaintDC dc( this );
- if ( IsEmpty() )
+ if ( IsEmpty() || m_freezeCount )
{
- // empty control. nothing to draw
+ // nothing to draw or not the moment to draw it
return;
}
// what we're trying to avoid
if ( !IsVirtual() && (command != wxEVT_COMMAND_LIST_DELETE_ITEM) )
{
- GetLine(line)->GetItem( 0, le.m_item );
+ if ( line != (size_t)-1 )
+ {
+ GetLine(line)->GetItem( 0, le.m_item );
+ }
+ //else: this happens for wxEVT_COMMAND_LIST_ITEM_FOCUSED event
}
//else: there may be no more such item
GetParent()->GetEventHandler()->ProcessEvent( le );
}
-void wxListMainWindow::OnFocusLine( size_t WXUNUSED(line) )
+void wxListMainWindow::ChangeCurrent(size_t current)
{
-// SendNotify( line, wxEVT_COMMAND_LIST_ITEM_FOCUSSED );
-}
+ m_current = current;
-void wxListMainWindow::OnUnfocusLine( size_t WXUNUSED(line) )
-{
-// SendNotify( line, wxEVT_COMMAND_LIST_ITEM_UNFOCUSSED );
+ SendNotify(current, wxEVT_COMMAND_LIST_ITEM_FOCUSED);
}
void wxListMainWindow::EditLabel( long item )
if ( IsSingleSel() || !(event.ControlDown() || event.ShiftDown()) )
{
HighlightAll( FALSE );
- m_current = current;
+
+ ChangeCurrent(current);
ReverseHighlight(m_current);
}
{
if (event.ControlDown())
{
- m_current = current;
+ ChangeCurrent(current);
ReverseHighlight(m_current);
}
else if (event.ShiftDown())
{
- m_current = current;
+ ChangeCurrent(current);
size_t lineFrom = oldCurrent,
lineTo = current;
if (m_current != oldCurrent)
{
RefreshLine( oldCurrent );
- OnUnfocusLine( oldCurrent );
- OnFocusLine( m_current );
}
// forceClick is only set if the previous click was on another item
// items anyhow
if ( event.ShiftDown() && !IsSingleSel() )
{
- m_current = newCurrent;
+ ChangeCurrent(newCurrent);
// select all the items between the old and the new one
if ( oldCurrent > newCurrent )
if ( !event.ControlDown() )
HighlightAll(FALSE);
- m_current = newCurrent;
+ ChangeCurrent(newCurrent);
HighlightLine( oldCurrent, FALSE );
RefreshLine( oldCurrent );
}
}
- OnUnfocusLine( oldCurrent );
- OnFocusLine( m_current );
RefreshLine( m_current );
MoveToFocus();
nevent.SetDirection( !event.ShiftDown() );
nevent.SetEventObject( GetParent()->GetParent() );
nevent.SetCurrentFocus( m_parent );
- if (GetParent()->GetParent()->GetEventHandler()->ProcessEvent( nevent )) return;
+ if (GetParent()->GetParent()->GetEventHandler()->ProcessEvent( nevent ))
+ return;
}
/* no item -> nothing to do */
case WXK_SPACE:
if ( IsSingleSel() )
{
- wxListEvent le( wxEVT_COMMAND_LIST_ITEM_ACTIVATED,
- GetParent()->GetId() );
- le.SetEventObject( GetParent() );
- le.m_itemIndex = m_current;
- GetLine(m_current)->GetItem( 0, le.m_item );
- GetParent()->GetEventHandler()->ProcessEvent( le );
+ SendNotify( m_current, wxEVT_COMMAND_LIST_ITEM_ACTIVATED );
if ( IsHighlighted(m_current) )
{
case WXK_RETURN:
case WXK_EXECUTE:
- {
- wxListEvent le( wxEVT_COMMAND_LIST_ITEM_ACTIVATED,
- GetParent()->GetId() );
- le.SetEventObject( GetParent() );
- le.m_itemIndex = m_current;
- GetLine(m_current)->GetItem( 0, le.m_item );
- GetParent()->GetEventHandler()->ProcessEvent( le );
- }
+ SendNotify( m_current, wxEVT_COMMAND_LIST_ITEM_ACTIVATED );
break;
default:
// don't do anything if this item is already focused
if ( item != m_current )
{
- OnUnfocusLine( m_current );
- m_current = item;
- OnFocusLine( m_current );
+ ChangeCurrent(item);
if ( oldCurrent != (size_t)-1 )
{
// don't do anything if this item is not focused
if ( item == m_current )
{
- OnUnfocusLine( m_current );
- m_current = (size_t)-1;
+ ResetCurrent();
RefreshLine( oldCurrent );
}
// single sel mode
if ( m_current != item )
{
- OnUnfocusLine( m_current );
- m_current = item;
- OnFocusLine( m_current );
+ ChangeCurrent(item);
if ( oldCurrent != (size_t)-1 )
{
{
if ( !HasCurrent() && !IsEmpty() )
{
- m_current = 0;
- }
-
- if ( m_current != (size_t)-1 )
- {
- OnFocusLine( m_current );
+ ChangeCurrent(0);
}
}
}
}
-// -------------------------------------------------------------------------------------
-// wxListEvent
-// -------------------------------------------------------------------------------------
-
-IMPLEMENT_DYNAMIC_CLASS(wxListEvent, wxNotifyEvent)
-
-wxListEvent::wxListEvent( wxEventType commandType, int id )
- : wxNotifyEvent( commandType, id )
-{
- m_code = 0;
- m_itemIndex = 0;
- m_oldItemIndex = 0;
- m_col = 0;
- m_cancelled = FALSE;
- m_pointDrag.x = 0;
- 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
// -------------------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxListCtrl, wxControl)
IMPLEMENT_DYNAMIC_CLASS(wxListView, wxListCtrl)
+IMPLEMENT_DYNAMIC_CLASS(wxListEvent, wxNotifyEvent)
+
BEGIN_EVENT_TABLE(wxListCtrl,wxControl)
EVT_SIZE(wxListCtrl::OnSize)
EVT_IDLE(wxListCtrl::OnIdle)
wxListCtrl::~wxListCtrl()
{
- if ( m_mainWin )
- m_mainWin->ResetCurrent();
-
if (m_ownsImageListNormal)
delete m_imageListNormal;
if (m_ownsImageListSmall)
{
size_t count = m_mainWin->m_columns.GetCount();
for ( size_t n = 0; n < count; n++ )
- DeleteColumn(n);
+ DeleteColumn(0);
return TRUE;
}
m_mainWin->RefreshLines(itemFrom, itemTo);
}
+void wxListCtrl::Freeze()
+{
+ m_mainWin->Freeze();
+}
+
+void wxListCtrl::Thaw()
+{
+ m_mainWin->Thaw();
+}
+
#endif // wxUSE_LISTCTRL