listctrl.cpp

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 2,239 行 · 第 1/5 页

CPP
2,239
字号
{
    wxListItemDataList::compatibility_iterator node = m_items.Item( index );
    wxCHECK_RET( node, _T("invalid column index in SetItem") );

    wxListItemData *item = node->GetData();
    item->SetItem( info );
}

void wxListLineData::GetItem( int index, wxListItem &info )
{
    wxListItemDataList::compatibility_iterator node = m_items.Item( index );
    if (node)
    {
        wxListItemData *item = node->GetData();
        item->GetItem( info );
    }
}

wxString wxListLineData::GetText(int index) const
{
    wxString s;

    wxListItemDataList::compatibility_iterator node = m_items.Item( index );
    if (node)
    {
        wxListItemData *item = node->GetData();
        s = item->GetText();
    }

    return s;
}

void wxListLineData::SetText( int index, const wxString s )
{
    wxListItemDataList::compatibility_iterator node = m_items.Item( index );
    if (node)
    {
        wxListItemData *item = node->GetData();
        item->SetText( s );
    }
}

void wxListLineData::SetImage( int index, int image )
{
    wxListItemDataList::compatibility_iterator node = m_items.Item( index );
    wxCHECK_RET( node, _T("invalid column index in SetImage()") );

    wxListItemData *item = node->GetData();
    item->SetImage(image);
}

int wxListLineData::GetImage( int index ) const
{
    wxListItemDataList::compatibility_iterator node = m_items.Item( index );
    wxCHECK_MSG( node, -1, _T("invalid column index in GetImage()") );

    wxListItemData *item = node->GetData();
    return item->GetImage();
}

wxListItemAttr *wxListLineData::GetAttr() const
{
    wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
    wxCHECK_MSG( node, NULL, _T("invalid column index in GetAttr()") );

    wxListItemData *item = node->GetData();
    return item->GetAttr();
}

void wxListLineData::SetAttr(wxListItemAttr *attr)
{
    wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
    wxCHECK_RET( node, _T("invalid column index in SetAttr()") );

    wxListItemData *item = node->GetData();
    item->SetAttr(attr);
}

bool wxListLineData::SetAttributes(wxDC *dc,
                                   const wxListItemAttr *attr,
                                   bool highlighted)
{
    wxWindow *listctrl = m_owner->GetParent();

    // fg colour

    // don't use foreground colour for drawing highlighted items - this might
    // make them completely invisible (and there is no way to do bit
    // arithmetics on wxColour, unfortunately)
    wxColour colText;
    if ( highlighted )
    {
        colText = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
    }
    else
    {
        if ( attr && attr->HasTextColour() )
        {
            colText = attr->GetTextColour();
        }
        else
        {
            colText = listctrl->GetForegroundColour();
        }
    }

    dc->SetTextForeground(colText);

    // font
    wxFont font;
    if ( attr && attr->HasFont() )
    {
        font = attr->GetFont();
    }
    else
    {
        font = listctrl->GetFont();
    }

    dc->SetFont(font);

    // bg colour
    bool hasBgCol = attr && attr->HasBackgroundColour();
    if ( highlighted || hasBgCol )
    {
        if ( highlighted )
        {
            dc->SetBrush( *m_owner->GetHighlightBrush() );
        }
        else
        {
            dc->SetBrush(wxBrush(attr->GetBackgroundColour(), wxSOLID));
        }

        dc->SetPen( *wxTRANSPARENT_PEN );

        return true;
    }

    return false;
}

void wxListLineData::Draw( wxDC *dc )
{
    wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
    wxCHECK_RET( node, _T("no subitems at all??") );

    bool highlighted = IsHighlighted();

    wxListItemAttr *attr = GetAttr();

    if ( SetAttributes(dc, attr, highlighted) )
    {
        dc->DrawRectangle( m_gi->m_rectHighlight );
    }

    // just for debugging to better see where the items are
#if 0
    dc->SetPen(*wxRED_PEN);
    dc->SetBrush(*wxTRANSPARENT_BRUSH);
    dc->DrawRectangle( m_gi->m_rectAll );
    dc->SetPen(*wxGREEN_PEN);
    dc->DrawRectangle( m_gi->m_rectIcon );
#endif // 0

    wxListItemData *item = node->GetData();
    if (item->HasImage())
    {
        // centre the image inside our rectangle, this looks nicer when items
        // ae aligned in a row
        const wxRect& rectIcon = m_gi->m_rectIcon;

        m_owner->DrawImage(item->GetImage(), dc, rectIcon.x, rectIcon.y);
    }

    if (item->HasText())
    {
        const wxRect& rectLabel = m_gi->m_rectLabel;

        wxDCClipper clipper(*dc, rectLabel);
        dc->DrawText(item->GetText(), rectLabel.x, rectLabel.y);
    }
}

void wxListLineData::DrawInReportMode( wxDC *dc,
                                       const wxRect& rect,
                                       const wxRect& rectHL,
                                       bool highlighted )
{
    // TODO: later we should support setting different attributes for
    //       different columns - to do it, just add "col" argument to
    //       GetAttr() and move these lines into the loop below
    wxListItemAttr *attr = GetAttr();
    if ( SetAttributes(dc, attr, highlighted) )
    {
        dc->DrawRectangle( rectHL );
    }

    wxCoord x = rect.x + HEADER_OFFSET_X,
            y = rect.y + (LINE_SPACING + EXTRA_HEIGHT) / 2;

    size_t col = 0;
    for ( wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
          node;
          node = node->GetNext(), col++ )
    {
        wxListItemData *item = node->GetData();

        int width = m_owner->GetColumnWidth(col);
        int xOld = x;
        x += width;

        if ( item->HasImage() )
        {
            int ix, iy;
            m_owner->DrawImage( item->GetImage(), dc, xOld, y );
            m_owner->GetImageSize( item->GetImage(), ix, iy );

            ix += IMAGE_MARGIN_IN_REPORT_MODE;

            xOld += ix;
            width -= ix;
        }

        wxDCClipper clipper(*dc, xOld, y, width - 8, rect.height);

        if ( item->HasText() )
        {
            DrawTextFormatted(dc, item->GetText(), col, xOld, y, width - 8);
        }
    }
}

void wxListLineData::DrawTextFormatted(wxDC *dc,
                                       const wxString &text,
                                       int col,
                                       int x,
                                       int y,
                                       int width)
{
    wxString drawntext, ellipsis;
    wxCoord w, h, base_w;
    wxListItem item;

    // 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
        m_owner->GetColumn(col, item);
        switch ( item.GetAlign() )
        {
            default:
                wxFAIL_MSG( _T("unknown list item format") );
                // fall through

            case wxLIST_FORMAT_LEFT:
                // nothing to do
                break;

            case wxLIST_FORMAT_RIGHT:
                x += width - w;
                break;

            case wxLIST_FORMAT_CENTER:
                x += (width - w) / 2;
                break;
        }

        dc->DrawText(text, x, y);
    }
    else // otherwise, truncate and add an ellipsis if possible
    {
        // determine the base width
        ellipsis = wxString(wxT("..."));
        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);
        while (len > 1)
        {
            dc->GetTextExtent(drawntext.Last(), &w_c, &h_c);
            drawntext.RemoveLast();
            len--;
            w -= w_c;
            if (w + base_w <= width)
                break;
        }

        // if still not enough space, remove ellipsis characters
        while (ellipsis.Length() > 0 && w + base_w > width)
        {
            ellipsis = ellipsis.Left(ellipsis.Length() - 1);
            dc->GetTextExtent(ellipsis, &base_w, &h);
        }

        // now draw the text
        dc->DrawText(drawntext, x, y);
        dc->DrawText(ellipsis, x + w, y);
    }
}

bool wxListLineData::Highlight( bool on )
{
    wxCHECK_MSG( !IsVirtual(), false, _T("unexpected call to Highlight") );

    if ( on == m_highlighted )
        return false;

    m_highlighted = on;

    return true;
}

void wxListLineData::ReverseHighlight( void )
{
    Highlight(!IsHighlighted());
}

//-----------------------------------------------------------------------------
//  wxListHeaderWindow
//-----------------------------------------------------------------------------

IMPLEMENT_DYNAMIC_CLASS(wxListHeaderWindow,wxWindow)

BEGIN_EVENT_TABLE(wxListHeaderWindow,wxWindow)
    EVT_PAINT         (wxListHeaderWindow::OnPaint)
    EVT_MOUSE_EVENTS  (wxListHeaderWindow::OnMouse)
    EVT_SET_FOCUS     (wxListHeaderWindow::OnSetFocus)
END_EVENT_TABLE()

void wxListHeaderWindow::Init()
{
    m_currentCursor = (wxCursor *) NULL;
    m_isDragging = false;
    m_dirty = false;
}

wxListHeaderWindow::wxListHeaderWindow()
{
    Init();

    m_owner = (wxListMainWindow *) NULL;
    m_resizeCursor = (wxCursor *) NULL;
}

wxListHeaderWindow::wxListHeaderWindow( wxWindow *win,
                                        wxWindowID id,
                                        wxListMainWindow *owner,
                                        const wxPoint& pos,
                                        const wxSize& size,
                                        long style,
                                        const wxString &name )
                  : wxWindow( win, id, pos, size, style, name )
{
    Init();

    m_owner = owner;
    m_resizeCursor = new wxCursor( wxCURSOR_SIZEWE );

#if _USE_VISATTR
    wxVisualAttributes attr = wxPanel::GetClassDefaultAttributes();
    SetOwnForegroundColour( attr.colFg );
    SetOwnBackgroundColour( attr.colBg );
    if (!m_hasFont)
        SetOwnFont( attr.font );
#else
    SetOwnForegroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
    SetOwnBackgroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
    if (!m_hasFont)
        SetOwnFont( wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT ));
#endif
}

wxListHeaderWindow::~wxListHeaderWindow()
{
    delete m_resizeCursor;
}

#ifdef __WXUNIVERSAL__
#include "wx/univ/renderer.h"
#include "wx/univ/theme.h"
#endif

// shift the DC origin to match the position of the main window horz
// scrollbar: this allows us to always use logical coords
void wxListHeaderWindow::AdjustDC(wxDC& dc)
{
    int xpix;
    m_owner->GetScrollPixelsPerUnit( &xpix, NULL );

    int x;
    m_owner->GetViewStart( &x, NULL );

    // account for the horz scrollbar offset
    dc.SetDeviceOrigin( -x * xpix, 0 );
}

void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
{
    wxPaintDC dc( this );

    PrepareDC( dc );
    AdjustDC( dc );

    dc.BeginDrawing();

    dc.SetFont( GetFont() );

    // width and height of the entire header window
    int w, h;
    GetClientSize( &w, &h );
    m_owner->CalcUnscrolledPosition(w, 0, &w, NULL);

    dc.SetBackgroundMode(wxTRANSPARENT);

    dc.SetTextForeground(GetForegroundColour());

    int x = HEADER_OFFSET_X;

    int numColumns = m_owner->GetColumnCount();
    wxListItem item;
    for ( int i = 0; i < numColumns && x < w; i++ )
    {
        m_owner->GetColumn( i, item );
        int wCol = item.m_width;

        // the width of the rect to draw: make it smaller to fit entirely
        // inside the column rect
#ifdef __WXMAC__
        int cw = wCol ;
        int ch = h ;
#else
        int cw = wCol - 2;
        int ch = h-2 ;
#endif
        wxRendererNative::Get().DrawHeaderButton
                                (
                                    this,
                                    dc,
                                    wxRect(x, HEADER_OFFSET_Y, cw, ch),
                                    m_parent->IsEnabled() ? 0
                                                          : (int)wxCONTROL_DISABLED
                                );

        // see if we have enough space for the column label

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?