// the space between the image and the text in the report mode
static const int IMAGE_MARGIN_IN_REPORT_MODE = 5;
+// the space between the image and the text in the report mode in header
+static const int HEADER_IMAGE_MARGIN_IN_REPORT_MODE = 2;
+
// ============================================================================
// private classes
// ============================================================================
// 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;
if ( m_mask & wxLIST_MASK_WIDTH )
SetWidth(item.m_width);
-
+
if ( m_mask & wxLIST_MASK_STATE )
SetState(item.m_state);
}
if ( highlighted )
#ifdef __WXMAC__
{
- if (m_owner->HasFocus())
+ if (m_owner->HasFocus()
+#ifdef __WXMAC__
+ && IsControlActive( (ControlRef)m_owner->GetHandle() )
+#endif
+ )
colText = *wxWHITE;
else
colText = *wxBLACK;
if (highlighted)
{
int flags = wxCONTROL_SELECTED;
- if (m_owner->HasFocus())
+ if (m_owner->HasFocus()
+#ifdef __WXMAC__
+ && IsControlActive( (ControlRef)m_owner->GetHandle() )
+#endif
+ )
flags |= wxCONTROL_FOCUSED;
wxRendererNative::Get().DrawItemSelectionRect( m_owner, *dc, m_gi->m_rectHighlight, flags );
-
+
}
else
{
if (highlighted)
{
int flags = wxCONTROL_SELECTED;
- if (m_owner->HasFocus())
+ if (m_owner->HasFocus()
+#ifdef __WXMAC__
+ && IsControlActive( (ControlRef)m_owner->GetHandle() )
+#endif
+ )
flags |= wxCONTROL_FOCUSED;
wxRendererNative::Get().DrawItemSelectionRect( m_owner, *dc, rectHL, flags );
}
}
void wxListLineData::DrawTextFormatted(wxDC *dc,
- const wxString &text,
+ const wxString& textOrig,
int col,
int x,
int yMid,
int width)
{
+ // we don't support displaying multiple lines currently (and neither does
+ // wxMSW FWIW) so just merge all the lines
+ wxString text(textOrig);
+ text.Replace(_T("\n"), _T(" "));
+
wxCoord w, h;
dc->GetTextExtent(text, &w, &h);
if (!m_parent->IsEnabled())
flags |= wxCONTROL_DISABLED;
-// NB: The code below is not really Mac-specific, but since we are close
+// 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) &&
+ if ( !m_owner->IsVirtual() && (item.m_mask & wxLIST_MASK_STATE) &&
(item.m_state & wxLIST_STATE_SELECTED) )
flags |= wxCONTROL_SELECTED;
#endif
wLabel += 2 * EXTRA_WIDTH;
// and the width of the icon, if any
- static const int MARGIN_BETWEEN_TEXT_AND_ICON = 2;
int ix = 0, iy = 0; // init them just to suppress the compiler warnings
const int image = item.m_image;
wxImageList *imageList;
if ( imageList )
{
imageList->GetSize(image, ix, iy);
- wLabel += ix + MARGIN_BETWEEN_TEXT_AND_ICON;
+ wLabel += ix + HEADER_IMAGE_MARGIN_IN_REPORT_MODE;
}
}
else
break;
}
+ // draw the text and image clipping them so that they
+ // don't overwrite the column boundary
+ wxDCClipper clipper(dc, x, HEADER_OFFSET_Y, cw, h - 4 );
+
// if we have an image, draw it on the right of the label
if ( imageList )
{
(
image,
dc,
- xAligned + wLabel - ix - MARGIN_BETWEEN_TEXT_AND_ICON,
+ xAligned + wLabel - ix - HEADER_IMAGE_MARGIN_IN_REPORT_MODE,
HEADER_OFFSET_Y + (h - 4 - iy)/2,
wxIMAGELIST_DRAW_TRANSPARENT
);
-
- cw -= ix + MARGIN_BETWEEN_TEXT_AND_ICON;
}
- // draw the text clipping it so that it doesn't overwrite the column
- // boundary
- wxDCClipper clipper(dc, x, HEADER_OFFSET_Y, cw, h - 4 );
-
dc.DrawText( item.GetText(),
xAligned + EXTRA_WIDTH, h / 2 - hLabel / 2 ); //HEADER_OFFSET_Y + EXTRA_HEIGHT );
{
wxListItem colItem;
m_owner->GetColumn(i, colItem);
- long state = colItem.GetState();
+ long state = colItem.GetState();
if (i == m_column)
colItem.SetState(state | wxLIST_STATE_SELECTED);
else
m_owner->SetColumn(i, colItem);
}
}
-
+
SendListEvent( event.LeftDown()
? wxEVT_COMMAND_LIST_COL_CLICK
: wxEVT_COMMAND_LIST_COL_RIGHT_CLICK,
{
const wxString value = m_text->GetValue();
- if ( value == m_startValue )
- // nothing changed, always accept
- return true;
-
+ // notice that we should always call OnRenameAccept() to generate the "end
+ // label editing" event, even if the user hasn't really changed anything
if ( !m_owner->OnRenameAccept(m_itemEdited, value) )
+ {
// vetoed by the user
return false;
+ }
- // accepted, do rename the item
- m_owner->SetItemText(m_itemEdited, value);
+ // accepted, do rename the item (unless nothing changed)
+ if ( value != m_startValue )
+ m_owner->SetItemText(m_itemEdited, value);
return true;
}
EVT_MOUSE_EVENTS (wxListMainWindow::OnMouse)
EVT_CHAR (wxListMainWindow::OnChar)
EVT_KEY_DOWN (wxListMainWindow::OnKeyDown)
- EVT_KEY_UP (wxListMainWindow::OnKeyUp)
+ EVT_KEY_UP (wxListMainWindow::OnKeyUp)
EVT_SET_FOCUS (wxListMainWindow::OnSetFocus)
EVT_KILL_FOCUS (wxListMainWindow::OnKillFocus)
EVT_SCROLLWIN (wxListMainWindow::OnScroll)
),
wxSOLID
);
-
+
m_highlightUnfocusedBrush = new wxBrush
(
wxSystemSettings::GetColour
if ( !InReportView() )
return GetLine(line)->m_gi->m_rectLabel;
+ int image_x = 0;
+ wxListLineData *data = GetLine(line);
+ wxListItemDataList::compatibility_iterator node = data->m_items.GetFirst();
+ if (node)
+ {
+ wxListItemData *item = node->GetData();
+ if ( item->HasImage() )
+ {
+ int ix, iy;
+ GetImageSize( item->GetImage(), ix, iy );
+ image_x = 3 + ix + IMAGE_MARGIN_IN_REPORT_MODE;
+ }
+ }
+
wxRect rect;
rect.x = HEADER_OFFSET_X;
rect.y = GetLineY(line);
wxRect rectLine;
int xOrig = dc.LogicalToDeviceX( 0 );
int yOrig = dc.LogicalToDeviceY( 0 );
-
+
// tell the caller cache to cache the data
if ( IsVirtual() )
{
wxPen pen(GetRuleColour(), 1, wxSOLID);
wxSize clientSize = GetClientSize();
- // Don't draw the first one
- for ( size_t i = visibleFrom + 1; i <= visibleTo; i++ )
+ size_t i = visibleFrom;
+ if (i == 0) i = 1; // Don't draw the first one
+ for ( ; i <= visibleTo; i++ )
{
dc.SetPen(pen);
dc.SetBrush( *wxTRANSPARENT_BRUSH );
{
int colWidth = GetColumnWidth(col);
x += colWidth;
- dc.DrawLine(x - dev_x - 2, firstItemRect.GetY() - 1 - dev_y,
- x - dev_x - 2, lastItemRect.GetBottom() + 1 - dev_y);
+ int x_pos = x - dev_x;
+ if (col < GetColumnCount()-1) x_pos -= 2;
+ dc.DrawLine(x_pos, firstItemRect.GetY() - 1 - dev_y,
+ x_pos, lastItemRect.GetBottom() + 1 - dev_y);
}
}
}
dc.DrawRectangle( rect );
#else
wxRendererNative::Get().DrawItemSelectionRect( this, dc, rect, wxCONTROL_CURRENT|wxCONTROL_FOCUSED );
-
+
#endif
}
}
{
wxListEvent le( command, GetParent()->GetId() );
le.SetEventObject( GetParent() );
-
+
le.m_itemIndex = line;
// set only for events which have position
{
m_current = current;
+ // as the current item changed, we shouldn't start editing it when the
+ // "slow click" timer expires as the click happened on another item
+ if ( m_renameTimer->IsRunning() )
+ m_renameTimer->Stop();
+
SendNotify(current, wxEVT_COMMAND_LIST_ITEM_FOCUSED);
}
// 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();
+ // Pending events dispatched by wxSafeYield might have changed the item
+ // count
+ if ( (size_t)item >= GetItemCount() )
+ return NULL;
+ }
+
wxTextCtrl * const text = (wxTextCtrl *)textControlClass->CreateObject();
m_textctrlWrapper = new wxListTextCtrlWrapper(this, text, item);
return m_textctrlWrapper->GetText();
m_textctrlWrapper->AcceptChangesAndFinish();
#endif // __WXMAC__
+ if ( event.LeftDown() )
+ SetFocus();
+
event.SetEventObject( GetParent() );
if ( GetParent()->GetEventHandler()->ProcessEvent( event) )
return;
bool forceClick = false;
if (event.ButtonDClick())
{
- m_renameTimer->Stop();
+ if ( m_renameTimer->IsRunning() )
+ m_renameTimer->Stop();
+
m_lastOnSame = false;
if ( current == m_lineLastClicked )
(hitResult == wxLIST_HITTEST_ONITEMLABEL) &&
HasFlag(wxLC_EDIT_LABELS) )
{
- m_renameTimer->Start( 100, true );
+ if (InReportView())
+ {
+ wxRect label = GetLineLabelRect( current );
+ if (label.Contains( x, y ))
+ m_renameTimer->Start( 250, true );
+
+ }
+ else
+ m_renameTimer->Start( 250, true );
}
}
else // !shift
{
// all previously selected items are unselected unless ctrl is held
- if ( !event.ControlDown() )
+ // in a multiselection control
+ if ( !event.ControlDown() || IsSingleSel() )
HighlightAll(false);
ChangeCurrent(newCurrent);
// refresh the old focus to remove it
RefreshLine( oldCurrent );
- if ( !event.ControlDown() )
- {
+ // in single selection mode we must always have a selected item
+ if ( !event.ControlDown() || IsSingleSel() )
HighlightLine( m_current, true );
- }
}
RefreshLine( m_current );
case WXK_SPACE:
if ( IsSingleSel() )
{
- SendNotify( m_current, wxEVT_COMMAND_LIST_ITEM_ACTIVATED );
-
- if ( IsHighlighted(m_current) )
+ if ( event.ControlDown() )
+ {
+ ReverseHighlight(m_current);
+ }
+ else // normal space press
{
- // don't unselect the item in single selection mode
- break;
+ SendNotify( m_current, wxEVT_COMMAND_LIST_ITEM_ACTIVATED );
}
- //else: select it in ReverseHighlight() below if unselected
}
-
- ReverseHighlight(m_current);
+ else // multiple selection
+ {
+ ReverseHighlight(m_current);
+ }
break;
case WXK_RETURN:
if (width == wxLIST_AUTOSIZE_USEHEADER)
{
width = GetTextLength(column->GetText());
+ width += 2*EXTRA_WIDTH;
+
+ // check for column header's image availability
+ const int image = column->GetImage();
+ if ( image != -1 )
+ {
+ if ( m_small_image_list )
+ {
+ int ix = 0, iy = 0;
+ m_small_image_list->GetSize(image, ix, iy);
+ width += ix + HEADER_IMAGE_MARGIN_IN_REPORT_MODE;
+ }
+ }
}
else if ( width == wxLIST_AUTOSIZE )
{
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
{
if (str.empty())
return wxNOT_FOUND;
-
+
long pos = start;
wxString str_upper = str.Upper();
if (pos < 0)
void wxListMainWindow::SortItems( wxListCtrlCompare fn, long data )
{
+ // selections won't make sense any more after sorting the items so reset
+ // them
+ HighlightAll(false);
+ ResetCurrent();
+
list_ctrl_compare_func_2 = fn;
list_ctrl_compare_data = data;
m_lines.Sort( list_ctrl_compare_func_1 );
void wxListMainWindow::OnScroll(wxScrollWinEvent& event)
{
- // update our idea of which lines are shown when we redraw the window the
- // next time
- ResetVisibleLinesRange();
-
// FIXME
#if ( defined(__WXGTK__) || defined(__WXMAC__) ) && !defined(__WXUNIVERSAL__)
wxScrolledWindow::OnScroll(event);
HandleOnScroll( event );
#endif
+ // update our idea of which lines are shown when we redraw the window the
+ // next time
+ ResetVisibleLinesRange();
+
if ( event.GetOrientation() == wxHORIZONTAL && HasHeader() )
{
wxGenericListCtrl* lc = GetListCtrl();
if ( !wxControl::Create( parent, id, pos, size, style, validator, name ) )
return false;
+ // this window itself shouldn't get the focus, only m_mainWin should
+ SetCanFocus(false);
+
// don't create the inner window with the border
style &= ~wxBORDER_MASK;
return info.m_data;
}
-bool wxGenericListCtrl::SetItemData( long item, long data )
+bool wxGenericListCtrl::SetItemPtrData( long item, wxUIntPtr data )
{
wxListItem info;
info.m_mask = wxLIST_MASK_DATA;
return info.GetBackgroundColour();
}
+int wxGenericListCtrl::GetScrollPos( int orient ) const
+{
+ return m_mainWin->GetScrollPos( orient );
+}
+
+void wxGenericListCtrl::SetScrollPos( int orient, int pos, bool refresh )
+{
+ m_mainWin->SetScrollPos( orient, pos, refresh );
+}
+
void wxGenericListCtrl::SetItemFont( long item, const wxFont &f )
{
wxListItem info;