⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 treelistctrl.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    dc->DrawLine( x+w-1, y, x+w-1, y+1 );
#else // !GTK, !Mac
    const int m_corner = 1;

    dc->SetBrush( *wxTRANSPARENT_BRUSH );

    dc->SetPen( *wxBLACK_PEN );
    dc->DrawLine( x+w-m_corner+1, y, x+w, y+h );  // right (outer)
    dc->DrawRectangle( x, y+h, w+1, 1 );          // bottom (outer)

    wxPen pen(wxSystemSettings::GetColour(
                  wxSYS_COLOUR_BTNSHADOW ), 1, wxSOLID);

    dc->SetPen( pen );
    dc->DrawLine( x+w-m_corner, y, x+w-1, y+h );  // right (inner)
    dc->DrawRectangle( x+1, y+h-1, w-2, 1 );      // bottom (inner)

    dc->SetPen( *wxWHITE_PEN );
    dc->DrawRectangle( x, y, w-m_corner+1, 1 );   // top (outer)
    dc->DrawRectangle( x, y, 1, h );              // left (outer)
    dc->DrawLine( x, y+h-1, x+1, y+h-1 );
    dc->DrawLine( x+w-1, y, x+w-1, y+1 );
#endif
}

// shift the DC origin to match the position of the main window horz
// scrollbar: this allows us to always use logical coords
void wxTreeListHeaderWindow::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 wxTreeListHeaderWindow::OnEraseBackground( wxEraseEvent& event )
{
}

void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
{
#ifdef __WXGTK__
    wxClientDC real_dc( this );
#else
    wxPaintDC real_dc( this );
#endif

    AdjustDC( real_dc );

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

    // Setup double buffering to eliminate the flicker
    wxMemoryDC dc;
    wxBitmap   buffer(w, h);
    dc.SelectObject(buffer);
    dc.SetBackground(wxBrush(GetBackgroundColour()));
    dc.Clear();
    
    dc.SetFont( GetFont() );
    dc.SetBackgroundMode(wxTRANSPARENT);

    // do *not* use the listctrl colour for headers - one day we will have a
    // function to set it separately
    //dc.SetTextForeground( *wxBLACK );
    dc.SetTextForeground(wxSystemSettings::
                            GetColour( wxSYS_COLOUR_WINDOWTEXT ));

    int x = HEADER_OFFSET_X;

    int numColumns = GetColumnCount();
    for ( int i = 0; i < numColumns && x < w; i++ )
    {
        if (!GetColumnShown (i)) continue;

        wxTreeListColumnInfo& column = GetColumn(i);
        int wCol = column.GetWidth();

        // the width of the rect to draw: make it smaller to fit entirely
        // inside the column rect
        int cw = wCol - 2;

        dc.SetPen( *wxWHITE_PEN );

        //DoDrawRect( &dc, x, HEADER_OFFSET_Y, cw, h-2 );
        wxRendererNative::Get().DrawHeaderButton(
            this, dc, wxRect(x, HEADER_OFFSET_Y, cw, h - 2),
            m_parent->IsEnabled() ? 0 : wxCONTROL_DISABLED);
        

        // if we have an image, draw it on the right of the label
        int image = column.GetImage(); //item.m_image;
        int ix = -2, iy = 0;
        wxImageList* imageList = m_owner->GetImageList();
        if(image != -1) {
            if(imageList) {
                imageList->GetSize(image, ix, iy);
            }
        //else: ignore the column image
        }

        int text_width = 0;
        int text_x = x;
        int image_offset = cw - ix - 1;

        switch(column.GetAlignment()) {
        case wxTL_ALIGN_LEFT:
            text_x += EXTRA_WIDTH;
            cw -= ix + 2;
            break;
        case wxTL_ALIGN_RIGHT:
            dc.GetTextExtent(column.GetText(), &text_width, NULL);
            text_x += cw - text_width - EXTRA_WIDTH;
            image_offset = 0;
            break;
        case wxTL_ALIGN_CENTER:
            dc.GetTextExtent(column.GetText(), &text_width, NULL);
            text_x += (cw - text_width)/2 + ix + 2;
            image_offset = (cw - text_width - ix - 2)/2;
            break;
        }

        // draw the image
        if(image != -1 && imageList) {
            imageList->Draw(image, dc, x + image_offset/*cw - ix - 1*/,
                            HEADER_OFFSET_Y + (h - 4 - iy)/2,
                            wxIMAGELIST_DRAW_TRANSPARENT);
        }

        // 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( column.GetText(),
                     text_x, HEADER_OFFSET_Y + EXTRA_HEIGHT );

        x += wCol;
    }

    int more_w = m_owner->GetSize().x - x -1;
    if (more_w > 0)
    {
        //DoDrawRect( &dc, x, HEADER_OFFSET_Y, more_w, h-2 );
        wxRendererNative::Get().DrawHeaderButton(
            this, dc, wxRect(x, HEADER_OFFSET_Y, more_w, h-2),
            m_parent->IsEnabled() ? 0 : wxCONTROL_DISABLED);
    }

    // Finish up by drawing the buffer to the real dc
    dc.SelectObject(wxNullBitmap);
    real_dc.DrawBitmap(buffer, 0, 0, false);
}

void wxTreeListHeaderWindow::DrawCurrent()
{
    int x1 = m_currentX;
    int y1 = 0;
    ClientToScreen( &x1, &y1 );

    int x2 = m_currentX-1;
#ifdef __WXMSW__
    ++x2; // but why ?
#endif
    int y2 = 0;
    m_owner->GetClientSize( NULL, &y2 );
    m_owner->ClientToScreen( &x2, &y2 );

    wxScreenDC dc;
    dc.SetLogicalFunction( wxINVERT );
    dc.SetPen( wxPen( *wxBLACK, 2, wxSOLID ) );
    dc.SetBrush( *wxTRANSPARENT_BRUSH );

    AdjustDC(dc);

    dc.DrawLine( x1, y1, x2, y2 );

    dc.SetLogicalFunction( wxCOPY );

    dc.SetPen( wxNullPen );
    dc.SetBrush( wxNullBrush );
}

void wxTreeListHeaderWindow::OnMouse( wxMouseEvent &event )
{
    // we want to work with logical coords
    int x;
    m_owner->CalcUnscrolledPosition(event.GetX(), 0, &x, NULL);
    int y = event.GetY();

    if (m_isDragging)
    {
        SendListEvent(wxEVT_COMMAND_LIST_COL_DRAGGING,
                      event.GetPosition());

        // we don't draw the line beyond our window, but we allow dragging it
        // there
        int w = 0;
        GetClientSize( &w, NULL );
        m_owner->CalcUnscrolledPosition(w, 0, &w, NULL);
        w -= 6;

        // erase the line if it was drawn
        if ( m_currentX < w )
            DrawCurrent();

        if (event.ButtonUp())
        {
            ReleaseMouse();
            m_isDragging = FALSE;
            m_dirty = TRUE;
            SetColumnWidth( m_column, m_currentX - m_minX );
            Refresh();
            SendListEvent(wxEVT_COMMAND_LIST_COL_END_DRAG,
                          event.GetPosition());
        }
        else
        {
            if (x > m_minX + 7)
                m_currentX = x;
            else
                m_currentX = m_minX + 7;

            // draw in the new location
            if ( m_currentX < w )
                DrawCurrent();
        }
    }
    else // not dragging
    {
        m_minX = 0;
        bool hit_border = FALSE;

        // end of the current column
        int xpos = 0;

        // find the column where this event occurred
        int countCol = GetColumnCount();
        for (int col = 0; col < countCol; col++)
        {
            if (!GetColumnShown (col)) continue;
            xpos += GetColumnWidth (col);
            m_column = col;

            if ( (abs(x-xpos) < 3) && (y < 22) )
            {
                // near the column border
                hit_border = TRUE;
                break;
            }

            if ( x < xpos )
            {
                // inside the column
                break;
            }

            m_minX = xpos;
        }

        if (event.LeftDown() || event.RightUp())
        {
            if (hit_border && event.LeftDown())
            {
                m_isDragging = TRUE;
                m_currentX = x;
                DrawCurrent();
                CaptureMouse();
                SendListEvent(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG,
                              event.GetPosition());
            }
            else // click on a column
            {
                SendListEvent( event.LeftDown()
                               ? wxEVT_COMMAND_LIST_COL_CLICK
                               : wxEVT_COMMAND_LIST_COL_RIGHT_CLICK,
                               event.GetPosition());
            }
        }
        else if (event.Moving())
        {
            bool setCursor;
            if (hit_border)
            {
                setCursor = m_currentCursor == wxSTANDARD_CURSOR;
                m_currentCursor = m_resizeCursor;
            }
            else
            {
                setCursor = m_currentCursor != wxSTANDARD_CURSOR;
                m_currentCursor = wxSTANDARD_CURSOR;
            }

            if ( setCursor )
                SetCursor(*m_currentCursor);
        }
    }
}

void wxTreeListHeaderWindow::OnSetFocus( wxFocusEvent &WXUNUSED(event) )
{
    m_owner->SetFocus();
}

void wxTreeListHeaderWindow::SendListEvent(wxEventType type, wxPoint pos)
{
    wxWindow *parent = GetParent();
    wxListEvent le( type, parent->GetId() );
    le.SetEventObject( parent );
    le.m_pointDrag = pos;

    // the position should be relative to the parent window, not
    // this one for compatibility with MSW and common sense: the
    // user code doesn't know anything at all about this header
    // window, so why should it get positions relative to it?
    le.m_pointDrag.y -= GetSize().y;

    le.m_col = m_column;
    parent->GetEventHandler()->ProcessEvent( le );
}

void wxTreeListHeaderWindow::AddColumn(const wxTreeListColumnInfo& col)
{
    m_columns.Add(col);
    m_total_col_width += col.GetWidth();
    //m_owner->GetHeaderWindow()->Refresh();
    //m_dirty = TRUE;
    m_owner->AdjustMyScrollbars();
    m_owner->m_dirty = TRUE;
    Refresh();
}

void wxTreeListHeaderWindow::SetColumnWidth(size_t column, size_t width)
{
    if(column < GetColumnCount()) {
        m_total_col_width -= m_columns[column].GetWidth();
        m_columns[column].SetWidth(width);
        m_total_col_width += width;
        m_owner->AdjustMyScrollbars();
        m_owner->m_dirty = TRUE;
        //m_dirty = TRUE;
        Refresh();
    }
}


void wxTreeListHeaderWindow::InsertColumn(size_t before,
                                          const wxTreeListColumnInfo& col)
{
    wxCHECK_RET(before < GetColumnCount(), wxT("Invalid column index"));
    m_columns.Insert(col, before);
    m_total_col_width += col.GetWidth();
    //m_dirty = TRUE;
    //m_owner->GetHeaderWindow()->Refresh();
    m_owner->AdjustMyScrollbars();
    m_owner->m_dirty = TRUE;
    Refresh();
}

void wxTreeListHeaderWindow::RemoveColumn(size_t column)
{
    wxCHECK_RET(column < GetColumnCount(), wxT("Invalid column"));
    m_total_col_width -= m_columns[column].GetWidth();
    m_columns.RemoveAt(column);
    //m_dirty = TRUE;
    m_owner->AdjustMyScrollbars();
    m_owner->m_dirty = TRUE;
    Refresh();
}

void wxTreeListHeaderWindow::SetColumn(size_t column,
                                       const wxTreeListColumnInfo& info)
{
    wxCHECK_RET(column < GetColumnCount(), wxT("Invalid column"));
    size_t w = m_columns[column].GetWidth();
    m_columns[column] = info;
    //m_owner->GetHeaderWindow()->Refresh();
    //m_dirty = TRUE;

⌨️ 快捷键说明

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