wxTextCtrl *GetText() const { return m_text; }
- void AcceptChangesAndFinish();
+ void EndEdit( bool discardChanges );
protected:
void OnChar( wxKeyEvent &event );
void OnKillFocus( wxFocusEvent &event );
bool AcceptChanges();
- void Finish();
+ void Finish( bool setfocus );
private:
wxListMainWindow *m_owner;
wxTextCtrl *m_text;
wxString m_startValue;
size_t m_itemEdited;
- bool m_finished;
bool m_aboutToFinish;
DECLARE_EVENT_TABLE()
// bring the selected item into view, scrolling to it if necessary
void MoveToItem(size_t item);
+ bool ScrollList( int WXUNUSED(dx), int dy );
+
// bring the current item into view
void MoveToFocus() { MoveToItem(m_current); }
return m_textctrlWrapper ? m_textctrlWrapper->GetText() : NULL;
}
- void FinishEditing(wxTextCtrl *text)
+ void ResetTextControl(wxTextCtrl *text)
{
delete text;
m_textctrlWrapper = NULL;
- SetFocusIgnoringChildren();
}
- // suspend/resume redrawing the control
- void Freeze();
- void Thaw();
-
void OnRenameTimer();
bool OnRenameAccept(size_t itemEdit, const wxString& value);
void OnRenameCancelled(size_t itemEdit);
wxBrush *m_highlightBrush,
*m_highlightUnfocusedBrush;
- // 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;
#ifdef __WXMAC__
{
if (m_owner->HasFocus()
-#ifdef __WXMAC__
+#if !defined(__WXUNIVERSAL__)
&& IsControlActive( (ControlRef)m_owner->GetHandle() )
#endif
)
{
int flags = wxCONTROL_SELECTED;
if (m_owner->HasFocus()
-#ifdef __WXMAC__
+#if defined( __WXMAC__ ) && !defined(__WXUNIVERSAL__)
&& IsControlActive( (ControlRef)m_owner->GetHandle() )
#endif
)
if (highlighted)
{
int flags = wxCONTROL_SELECTED;
- if (m_owner->HasFocus()
-#ifdef __WXMAC__
- && IsControlActive( (ControlRef)m_owner->GetHandle() )
-#endif
- )
+ if (m_owner->HasFocus())
flags |= wxCONTROL_FOCUSED;
wxRendererNative::Get().DrawItemSelectionRect( m_owner, *dc, rectHL, flags );
}
int xOld = x;
x += width;
+ const int wText = width - 8;
+ wxDCClipper clipper(*dc, xOld, rect.y, wText, rect.height);
+
if ( item->HasImage() )
{
int ix, iy;
}
if ( item->HasText() )
- DrawTextFormatted(dc, item->GetText(), col, xOld, yMid, width - 8);
+ DrawTextFormatted(dc, item->GetText(), col, xOld, yMid, wText);
}
}
{
m_owner = owner;
m_text = text;
- m_finished = false;
m_aboutToFinish = false;
wxRect rectLabel = owner->GetLineLabelRect(itemEdit);
m_text->PushEventHandler(this);
}
-void wxListTextCtrlWrapper::Finish()
+void wxListTextCtrlWrapper::EndEdit(bool discardChanges)
{
- if ( !m_finished )
+ m_aboutToFinish = true;
+
+ if ( discardChanges )
{
- m_finished = true;
-
- m_text->RemoveEventHandler(this);
- m_owner->FinishEditing(m_text);
+ m_owner->OnRenameCancelled(m_itemEdited);
+
+ Finish( true );
+ }
+ else
+ {
+ // Notify the owner about the changes
+ AcceptChanges();
- wxPendingDelete.Append( this );
+ // Even if vetoed, close the control (consistent with MSW)
+ Finish( true );
}
}
+void wxListTextCtrlWrapper::Finish( bool setfocus )
+{
+ m_text->RemoveEventHandler(this);
+ m_owner->ResetTextControl( m_text );
+
+ wxPendingDelete.Append( this );
+
+ if (setfocus)
+ m_owner->SetFocusIgnoringChildren();
+}
+
bool wxListTextCtrlWrapper::AcceptChanges()
{
const wxString value = m_text->GetValue();
return true;
}
-void wxListTextCtrlWrapper::AcceptChangesAndFinish()
-{
- m_aboutToFinish = true;
-
- // Notify the owner about the changes
- AcceptChanges();
-
- // Even if vetoed, close the control (consistent with MSW)
- Finish();
-}
-
void wxListTextCtrlWrapper::OnChar( wxKeyEvent &event )
{
switch ( event.m_keyCode )
{
case WXK_RETURN:
- AcceptChangesAndFinish();
+ EndEdit( false );
break;
case WXK_ESCAPE:
- m_owner->OnRenameCancelled( m_itemEdited );
- Finish();
+ EndEdit( true );
break;
default:
void wxListTextCtrlWrapper::OnKeyUp( wxKeyEvent &event )
{
- if (m_finished)
- {
- event.Skip();
- return;
- }
-
- // auto-grow the textctrl:
- wxSize parentSize = m_owner->GetSize();
- wxPoint myPos = m_text->GetPosition();
- wxSize mySize = m_text->GetSize();
- int 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;
- m_text->SetSize(sx, wxDefaultCoord);
-
+ if (m_aboutToFinish)
+ {
+ // auto-grow the textctrl:
+ wxSize parentSize = m_owner->GetSize();
+ wxPoint myPos = m_text->GetPosition();
+ wxSize mySize = m_text->GetSize();
+ int 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;
+ m_text->SetSize(sx, wxDefaultCoord);
+ }
+
event.Skip();
}
void wxListTextCtrlWrapper::OnKillFocus( wxFocusEvent &event )
{
- if ( !m_finished && !m_aboutToFinish )
+ if ( !m_aboutToFinish )
{
if ( !AcceptChanges() )
m_owner->OnRenameCancelled( m_itemEdited );
- Finish();
+ Finish( false );
}
// We must let the native text control handle focus
m_lineLastClicked =
m_lineSelectSingleOnUp =
m_lineBeforeLastClicked = (size_t)-1;
-
- m_freezeCount = 0;
}
wxListMainWindow::wxListMainWindow()
}
}
-void wxListMainWindow::Freeze()
-{
- m_freezeCount++;
-}
-
-void wxListMainWindow::Thaw()
-{
- wxCHECK_RET( m_freezeCount > 0, _T("thawing unfrozen list control?") );
-
- if ( --m_freezeCount == 0 )
- 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() || m_freezeCount )
+ if ( IsEmpty() )
+ {
// nothing to draw or not the moment to draw it
return;
+ }
if ( m_dirty )
+ {
// delay the repainting until we calculate all the items positions
return;
+ }
PrepareDC( dc );
RefreshLine(m_current);
}
}
- else // multi sel
+ else // multi selection
{
- HighlightLines(0, GetItemCount() - 1, on);
+ if ( !IsEmpty() )
+ HighlightLines(0, GetItemCount() - 1, on);
}
}
// 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_textctrlWrapper )
- m_textctrlWrapper->AcceptChangesAndFinish();
+ m_textctrlWrapper->EndEdit( false );
#endif // __WXMAC__
if ( event.LeftDown() )
if (event.RightDown())
{
SendNotify( (size_t)-1, wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK, event.GetPosition() );
-
+
wxContextMenuEvent evtCtx(
wxEVT_CONTEXT_MENU,
GetParent()->GetId(),
if (event.RightDown())
{
SendNotify( (size_t) -1, wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK, event.GetPosition() );
-
+
wxContextMenuEvent evtCtx(
wxEVT_CONTEXT_MENU,
GetParent()->GetId(),
Scroll( -1, rect.y / hLine );
if (rect.y + rect.height + 5 > view_y + client_h)
Scroll( -1, (rect.y + rect.height - client_h + hLine) / hLine );
+
+#ifdef __WXMAC__
+ // At least on Mac the visible lines value will get reset inside of
+ // Scroll *before* it actually scrolls the window because of the
+ // Update() that happens there, so it will still have the wrong value.
+ // So let's reset it again and wait for it to be recalculated in the
+ // next paint event. I would expect this problem to show up in wxGTK
+ // too but couldn't duplicate it there. Perhaps the order of events
+ // is different... --Robin
+ ResetVisibleLinesRange();
+#endif
}
else // !report
{
+ int sx = -1,
+ sy = -1;
+
if (rect.x-view_x < 5)
- Scroll( (rect.x - 5) / SCROLL_UNIT_X, -1 );
+ sx = (rect.x - 5) / SCROLL_UNIT_X;
if (rect.x + rect.width - 5 > view_x + client_w)
- Scroll( (rect.x + rect.width - client_w + SCROLL_UNIT_X) / SCROLL_UNIT_X, -1 );
+ sx = (rect.x + rect.width - client_w + SCROLL_UNIT_X) / SCROLL_UNIT_X;
+
+ if (rect.y-view_y < 5)
+ sy = (rect.y - 5) / hLine;
+ if (rect.y + rect.height - 5 > view_y + client_h)
+ sy = (rect.y + rect.height - client_h + hLine) / hLine;
+
+ Scroll(sx, sy);
}
}
+bool wxListMainWindow::ScrollList(int WXUNUSED(dx), int dy)
+{
+ if ( !InReportView() )
+ {
+ // TODO: this should work in all views but is not implemented now
+ return false;
+ }
+
+ size_t top, bottom;
+ GetVisibleLinesRange(&top, &bottom);
+
+ if ( bottom == (size_t)-1 )
+ return 0;
+
+ ResetVisibleLinesRange();
+
+ int hLine = GetLineHeight();
+
+ Scroll(-1, top + dy / hLine);
+
+#ifdef __WXMAC__
+ // see comment in MoveToItem() for why we do this
+ ResetVisibleLinesRange();
+#endif
+
+ return true;
+}
+
// ----------------------------------------------------------------------------
// keyboard handling
// ----------------------------------------------------------------------------
ke.SetEventObject( parent );
if (parent->GetEventHandler()->ProcessEvent( ke )) return;
- if (event.GetKeyCode() == WXK_TAB)
- {
- wxNavigationKeyEvent nevent;
- nevent.SetWindowChange( event.ControlDown() );
- nevent.SetDirection( !event.ShiftDown() );
- nevent.SetEventObject( GetParent()->GetParent() );
- nevent.SetCurrentFocus( m_parent );
- if (GetParent()->GetParent()->GetEventHandler()->ProcessEvent( nevent ))
- return;
- }
+ if ( HandleAsNavigationKey(event) )
+ return;
// no item -> nothing to do
if (!HasCurrent())
m_mainWin = new wxListMainWindow( this, wxID_ANY, wxPoint(0, 0), size, style );
-#ifdef __WXMAC_CARBON__
+#ifdef __WXMAC__
// Human Interface Guidelines ask us for a special font in this case
if ( GetWindowVariant() == wxWINDOW_VARIANT_NORMAL )
{
wxFont font;
- font.MacCreateThemeFont( kThemeViewsFont );
+ font.MacCreateFromThemeFont( kThemeViewsFont );
SetFont( font );
}
#endif
{
CreateHeaderWindow();
-#ifdef __WXMAC_CARBON__
+#ifdef __WXMAC__
if (m_headerWin)
{
wxFont font;
- font.MacCreateThemeFont( kThemeSmallSystemFont );
+ font.MacCreateFromThemeFont( kThemeSmallSystemFont );
m_headerWin->SetFont( font );
CalculateAndSetHeaderHeight();
}
return InsertColumn( col, item );
}
-bool wxGenericListCtrl::ScrollList( int WXUNUSED(dx), int WXUNUSED(dy) )
+bool wxGenericListCtrl::ScrollList( int dx, int dy )
{
- return 0;
+ return m_mainWin->ScrollList(dx, dy);
}
// Sort items.
}
}
-void wxGenericListCtrl::Freeze()
-{
- m_mainWin->Freeze();
-}
-
-void wxGenericListCtrl::Thaw()
-{
- m_mainWin->Thaw();
-}
-
#endif // wxUSE_LISTCTRL