// wxListLineData (internal)
//-----------------------------------------------------------------------------
-WX_DECLARE_LIST(wxListItemData, wxListItemDataList);
+WX_DECLARE_EXPORTED_LIST(wxListItemData, wxListItemDataList);
#include "wx/listimpl.cpp"
WX_DEFINE_LIST(wxListItemDataList)
void SetImage( int image ) { SetImage(0, image); }
int GetImage() const { return GetImage(0); }
+ void SetImage( int index, int image );
+ int GetImage( int index ) const;
+
bool HasImage() const { return GetImage() != -1; }
bool HasText() const { return !GetText(0).empty(); }
// draw the text on the DC with the correct justification; also add an
// ellipsis if the text is too large to fit in the current width
- void DrawTextFormatted(wxDC *dc, const wxString &text, int col, int x, int y, int width);
-
- // these are only used by GetImage/SetImage above, we don't support images
- // with subitems at the public API level yet
- void SetImage( int index, int image );
- int GetImage( int index ) const;
+ void DrawTextFormatted(wxDC *dc,
+ const wxString &text,
+ int col,
+ int x,
+ int yMid, // this is middle, not top, of the text
+ int width);
};
WX_DECLARE_EXPORTED_OBJARRAY(wxListLineData, wxListLineDataArray);
};
//-----------------------------------------------------------------------------
-// wxListTextCtrl (internal)
+// wxListTextCtrlWrapper: wraps a wxTextCtrl to make it work for inline editing
//-----------------------------------------------------------------------------
-class WXDLLEXPORT wxListTextCtrl: public wxTextCtrl
+class WXDLLEXPORT wxListTextCtrlWrapper : public wxEvtHandler
{
public:
- wxListTextCtrl(wxListMainWindow *owner, size_t itemEdit);
+ // NB: text must be a valid object but not Create()d yet
+ wxListTextCtrlWrapper(wxListMainWindow *owner,
+ wxTextCtrl *text,
+ size_t itemEdit);
+
+ wxTextCtrl *GetText() const { return m_text; }
void AcceptChangesAndFinish();
private:
wxListMainWindow *m_owner;
+ wxTextCtrl *m_text;
wxString m_startValue;
size_t m_itemEdited;
bool m_finished;
// wxListMainWindow (internal)
//-----------------------------------------------------------------------------
-WX_DECLARE_LIST(wxListHeaderData, wxListHeaderDataList);
+WX_DECLARE_EXPORTED_LIST(wxListHeaderData, wxListHeaderDataList);
#include "wx/listimpl.cpp"
WX_DEFINE_LIST(wxListHeaderDataList)
virtual ~wxListMainWindow();
- wxWindow *GetMainWindowOfCompositeControl() { return GetParent(); }
-
bool HasFlag(int flag) const { return m_parent->HasFlag(flag); }
// return true if this is a virtual list control
void MoveToFocus() { MoveToItem(m_current); }
// start editing the label of the given item
- void EditLabel( long item );
+ wxTextCtrl *EditLabel(long item,
+ wxClassInfo* textControlClass = CLASSINFO(wxTextCtrl));
+ wxTextCtrl *GetEditControl() const
+ {
+ return m_textctrlWrapper ? m_textctrlWrapper->GetText() : NULL;
+ }
+
+ void FinishEditing(wxTextCtrl *text)
+ {
+ delete text;
+ m_textctrlWrapper = NULL;
+ SetFocusIgnoringChildren();
+ }
// suspend/resume redrawing the control
void Freeze();
m_lineBeforeLastClicked,
m_lineSelectSingleOnUp;
- wxListTextCtrl* m_textctrl;
-
protected:
+ wxWindow *GetMainWindowOfCompositeControl() { return GetParent(); }
+
// the total count of items in a virtual list control
size_t m_countVirt;
// if this is > 0, the control is frozen and doesn't redraw itself
size_t m_freezeCount;
+ // wrapper around the text control currently used for in place editing or
+ // NULL if no item is being edited
+ wxListTextCtrlWrapper *m_textctrlWrapper;
+
+
DECLARE_DYNAMIC_CLASS(wxListMainWindow)
DECLARE_EVENT_TABLE()
dc->DrawRectangle( rectHL );
wxCoord x = rect.x + HEADER_OFFSET_X,
- y = rect.y + (LINE_SPACING + EXTRA_HEIGHT) / 2;
+ yMid = rect.y + rect.height/2;
size_t col = 0;
for ( wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
if ( item->HasImage() )
{
int ix, iy;
- m_owner->DrawImage( item->GetImage(), dc, xOld, y );
m_owner->GetImageSize( item->GetImage(), ix, iy );
+ m_owner->DrawImage( item->GetImage(), dc, xOld, yMid - iy/2 );
ix += IMAGE_MARGIN_IN_REPORT_MODE;
width -= ix;
}
- wxDCClipper clipper(*dc, xOld, y, width - 8, rect.height);
-
if ( item->HasText() )
- DrawTextFormatted(dc, item->GetText(), col, xOld, y, width - 8);
+ DrawTextFormatted(dc, item->GetText(), col, xOld, yMid, width - 8);
}
}
const wxString &text,
int col,
int x,
- int y,
+ int yMid,
int width)
{
- wxString drawntext, ellipsis;
- wxCoord w, h, base_w;
- wxListItem item;
+ wxCoord w, h;
+ dc->GetTextExtent(text, &w, &h);
+
+ const wxCoord y = yMid - (h + 1)/2;
+
+ wxDCClipper clipper(*dc, x, y, width, h);
// determine if the string can fit inside the current width
- dc->GetTextExtent(text, &w, &h);
if (w <= width)
{
// it can, draw it using the items alignment
+ wxListItem item;
m_owner->GetColumn(col, item);
switch ( item.GetAlign() )
{
else // otherwise, truncate and add an ellipsis if possible
{
// determine the base width
- ellipsis = wxString(wxT("..."));
+ wxString ellipsis(wxT("..."));
+ wxCoord base_w;
dc->GetTextExtent(ellipsis, &base_w, &h);
// continue until we have enough space or only one character left
wxCoord w_c, h_c;
size_t len = text.Length();
- drawntext = text.Left(len);
+ wxString drawntext = text.Left(len);
while (len > 1)
{
dc->GetTextExtent(drawntext.Last(), &w_c, &h_c);
PrepareDC( dc );
AdjustDC( dc );
- dc.BeginDrawing();
-
dc.SetFont( GetFont() );
// width and height of the entire header window
x += wCol;
}
-
- dc.EndDrawing();
}
void wxListHeaderWindow::DrawCurrent()
}
//-----------------------------------------------------------------------------
-// wxListTextCtrl (internal)
+// wxListTextCtrlWrapper (internal)
//-----------------------------------------------------------------------------
-BEGIN_EVENT_TABLE(wxListTextCtrl,wxTextCtrl)
- EVT_CHAR (wxListTextCtrl::OnChar)
- EVT_KEY_UP (wxListTextCtrl::OnKeyUp)
- EVT_KILL_FOCUS (wxListTextCtrl::OnKillFocus)
+BEGIN_EVENT_TABLE(wxListTextCtrlWrapper, wxEvtHandler)
+ EVT_CHAR (wxListTextCtrlWrapper::OnChar)
+ EVT_KEY_UP (wxListTextCtrlWrapper::OnKeyUp)
+ EVT_KILL_FOCUS (wxListTextCtrlWrapper::OnKillFocus)
END_EVENT_TABLE()
-wxListTextCtrl::wxListTextCtrl(wxListMainWindow *owner, size_t itemEdit)
+wxListTextCtrlWrapper::wxListTextCtrlWrapper(wxListMainWindow *owner,
+ wxTextCtrl *text,
+ size_t itemEdit)
: m_startValue(owner->GetItemText(itemEdit)),
m_itemEdited(itemEdit)
{
m_owner = owner;
+ m_text = text;
m_finished = false;
m_aboutToFinish = false;
m_owner->CalcScrolledPosition(rectLabel.x, rectLabel.y,
&rectLabel.x, &rectLabel.y);
- (void)Create(owner, wxID_ANY, m_startValue,
- wxPoint(rectLabel.x-4,rectLabel.y-4),
- wxSize(rectLabel.width+11,rectLabel.height+8));
+ m_text->Create(owner, wxID_ANY, m_startValue,
+ wxPoint(rectLabel.x-4,rectLabel.y-4),
+ wxSize(rectLabel.width+11,rectLabel.height+8));
+ m_text->PushEventHandler(this);
}
-void wxListTextCtrl::Finish()
+void wxListTextCtrlWrapper::Finish()
{
if ( !m_finished )
{
- wxPendingDelete.Append(this);
- m_owner->m_textctrl = NULL;
-
m_finished = true;
- m_owner->SetFocusIgnoringChildren();
+ m_text->RemoveEventHandler(this);
+ m_owner->FinishEditing(m_text);
+
+ delete this;
}
}
-bool wxListTextCtrl::AcceptChanges()
+bool wxListTextCtrlWrapper::AcceptChanges()
{
- const wxString value = GetValue();
+ const wxString value = m_text->GetValue();
if ( value == m_startValue )
// nothing changed, always accept
return true;
}
-void wxListTextCtrl::AcceptChangesAndFinish()
+void wxListTextCtrlWrapper::AcceptChangesAndFinish()
{
m_aboutToFinish = true;
Finish();
}
-void wxListTextCtrl::OnChar( wxKeyEvent &event )
+void wxListTextCtrlWrapper::OnChar( wxKeyEvent &event )
{
switch ( event.m_keyCode )
{
}
}
-void wxListTextCtrl::OnKeyUp( wxKeyEvent &event )
+void wxListTextCtrlWrapper::OnKeyUp( wxKeyEvent &event )
{
if (m_finished)
{
// auto-grow the textctrl:
wxSize parentSize = m_owner->GetSize();
- wxPoint myPos = GetPosition();
- wxSize mySize = GetSize();
+ wxPoint myPos = m_text->GetPosition();
+ wxSize mySize = m_text->GetSize();
int sx, sy;
- GetTextExtent(GetValue() + _T("MM"), &sx, &sy);
+ m_text->GetTextExtent(m_text->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, wxDefaultCoord);
+ m_text->SetSize(sx, wxDefaultCoord);
event.Skip();
}
-void wxListTextCtrl::OnKillFocus( wxFocusEvent &event )
+void wxListTextCtrlWrapper::OnKillFocus( wxFocusEvent &event )
{
if ( !m_finished && !m_aboutToFinish )
{
m_lastOnSame = false;
m_renameTimer = new wxListRenameTimer( this );
- m_textctrl = NULL;
+ m_textctrlWrapper = NULL;
m_current =
m_lineLastClicked =
for ( size_t col = 0; col < countCol; col++ )
{
ld->SetText(col, listctrl->OnGetItemText(line, col));
- ld->SetImage(listctrl->OnGetItemColumnImage(line, col));
+ ld->SetImage(col, listctrl->OnGetItemColumnImage(line, col));
}
ld->SetAttr(listctrl->OnGetItemAttr(line));
{
wxCHECK_RET( m_freezeCount > 0, _T("thawing unfrozen list control?") );
- if ( !--m_freezeCount )
+ if ( --m_freezeCount == 0 )
Refresh();
}
int dev_x, dev_y;
CalcScrolledPosition( 0, 0, &dev_x, &dev_y );
- dc.BeginDrawing();
-
dc.SetFont( GetFont() );
if ( InReportView() )
}
}
#endif
-
- dc.EndDrawing();
}
void wxListMainWindow::HighlightAll( bool on )
SendNotify(current, wxEVT_COMMAND_LIST_ITEM_FOCUSED);
}
-void wxListMainWindow::EditLabel( long item )
+wxTextCtrl *wxListMainWindow::EditLabel(long item, wxClassInfo* textControlClass)
{
- wxCHECK_RET( (item >= 0) && ((size_t)item < GetItemCount()),
+ wxCHECK_MSG( (item >= 0) && ((size_t)item < GetItemCount()), NULL,
wxT("wrong index in wxGenericListCtrl::EditLabel()") );
+ wxASSERT_MSG( textControlClass->IsKindOf(CLASSINFO(wxTextCtrl)),
+ wxT("EditLabel() needs a text control") );
+
size_t itemEdit = (size_t)item;
wxListEvent le( wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT, GetParent()->GetId() );
le.SetEventObject( GetParent() );
le.m_itemIndex = item;
wxListLineData *data = GetLine(itemEdit);
- wxCHECK_RET( data, _T("invalid index in EditLabel()") );
+ wxCHECK_MSG( data, NULL, _T("invalid index in EditLabel()") );
data->GetItem( 0, le.m_item );
if ( GetParent()->GetEventHandler()->ProcessEvent( le ) && !le.IsAllowed() )
+ {
// vetoed by user code
- return;
+ return NULL;
+ }
// We have to call this here because the label in question might just have
// been added and no screen update taken place.
if ( m_dirty )
wxSafeYield();
- m_textctrl = new wxListTextCtrl(this, itemEdit);
- m_textctrl->SetFocus();
+ wxTextCtrl * const text = (wxTextCtrl *)textControlClass->CreateObject();
+ m_textctrlWrapper = new wxListTextCtrlWrapper(this, text, item);
+ return m_textctrlWrapper->GetText();
}
void wxListMainWindow::OnRenameTimer()
// shutdown the edit control when the mouse is clicked elsewhere on the
// listctrl because the order of events is different (or something like
// that), so explicitly end the edit if it is active.
- if ( event.LeftDown() && m_textctrl)
- m_textctrl->AcceptChangesAndFinish();
-#endif
+ if ( event.LeftDown() && m_textctrlWrapper )
+ m_textctrlWrapper->AcceptChangesAndFinish();
+#endif // __WXMAC__
event.SetEventObject( GetParent() );
if ( GetParent()->GetEventHandler()->ProcessEvent( event) )
if ( !hitResult )
{
- // outside of any item
+ // outside of any item, reset the selection and bail out
+ HighlightAll(false);
return;
}
{
m_headerHeight = h;
- m_headerWin->SetSize(m_headerWin->GetSize().x, m_headerHeight);
-
if ( HasHeader() )
ResizeReportView(true);
+ else //why is this needed if it doesn't have a header?
+ m_headerWin->SetSize(m_headerWin->GetSize().x, m_headerHeight);
}
}
}
bool
wxGenericListCtrl::SetItemImage( long item, int image, int WXUNUSED(selImage) )
+{
+ return SetItemColumnImage(item, 0, image);
+}
+
+bool
+wxGenericListCtrl::SetItemColumnImage( long item, long column, int image )
{
wxListItem info;
info.m_image = image;
info.m_mask = wxLIST_MASK_IMAGE;
info.m_itemId = item;
+ info.m_col = column;
m_mainWin->SetItem( info );
return true;
}
return true;
}
-void wxGenericListCtrl::Edit( long item )
+wxTextCtrl *wxGenericListCtrl::EditLabel(long item,
+ wxClassInfo* textControlClass)
{
- m_mainWin->EditLabel( item );
+ return m_mainWin->EditLabel( item, textControlClass );
+}
+
+wxTextCtrl *wxGenericListCtrl::GetEditControl() const
+{
+ return m_mainWin->GetEditControl();
}
bool wxGenericListCtrl::EnsureVisible( long item )
if ( showHeader )
{
m_headerWin->SetSize( 0, 0, cw, m_headerHeight );
- m_mainWin->SetSize( 0, m_headerHeight + 1, cw, ch - m_headerHeight - 1 );
+ if(ch > m_headerHeight)
+ m_mainWin->SetSize( 0, m_headerHeight + 1,
+ cw, ch - m_headerHeight - 1 );
+ else
+ m_mainWin->SetSize( 0, m_headerHeight + 1,
+ cw, 0);
}
else // no header window
{
#endif
}
+void wxGenericListCtrl::DoClientToScreen( int *x, int *y ) const
+{
+ return m_mainWin->DoClientToScreen(x, y);
+}
+
+void wxGenericListCtrl::DoScreenToClient( int *x, int *y ) const
+{
+ return m_mainWin->DoScreenToClient(x, y);
+}
+
void wxGenericListCtrl::SetFocus()
{
// The test in window.cpp fails as we are a composite
return OnGetItemImage(item);
return -1;
-
+}
wxListItemAttr *
wxGenericListCtrl::OnGetItemAttr(long WXUNUSED_UNLESS_DEBUG(item)) const
rectHeader.Offset(-x, -y);
m_headerWin->Refresh(eraseBackground, &rectHeader);
}
-
}
// Refresh the main window