winuniv.cpp

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

CPP
1,372
字号
    // disabled window can't keep focus
    if ( FindFocus() == this && GetParent() != NULL )
    {
        GetParent()->SetFocus();
    }

    if ( m_renderer )
    {
        // a window with renderer is drawn by ourselves and it has to be
        // refreshed to reflect its new status
        Refresh();
    }

    return true;
}

bool wxWindow::IsFocused() const
{
    wxWindow *self = wxConstCast(this, wxWindow);
    return self->FindFocus() == self;
}

bool wxWindow::IsPressed() const
{
    return false;
}

bool wxWindow::IsDefault() const
{
    return false;
}

bool wxWindow::IsCurrent() const
{
    return m_isCurrent;
}

bool wxWindow::SetCurrent(bool doit)
{
    if ( doit == m_isCurrent )
        return false;

    m_isCurrent = doit;

    if ( CanBeHighlighted() )
        Refresh();

    return true;
}

int wxWindow::GetStateFlags() const
{
    int flags = 0;
    if ( !IsEnabled() )
        flags |= wxCONTROL_DISABLED;

    // the following states are only possible if our application is active - if
    // it is not, even our default/focused controls shouldn't appear as such
    if ( wxTheApp->IsActive() )
    {
        if ( IsCurrent() )
            flags |= wxCONTROL_CURRENT;
        if ( IsFocused() )
            flags |= wxCONTROL_FOCUSED;
        if ( IsPressed() )
            flags |= wxCONTROL_PRESSED;
        if ( IsDefault() )
            flags |= wxCONTROL_ISDEFAULT;
    }

    return flags;
}

// ----------------------------------------------------------------------------
// size
// ----------------------------------------------------------------------------

void wxWindow::OnSize(wxSizeEvent& event)
{
    event.Skip();

    if ( m_scrollbarVert || m_scrollbarHorz )
    {
        PositionScrollbars();
    }

#if 0   // ndef __WXMSW__
    // Refresh the area (strip) previously occupied by the border

    if ( !HasFlag(wxFULL_REPAINT_ON_RESIZE) && IsShown() )
    {
        // This code assumes that wxSizeEvent.GetSize() returns
        // the area of the entire window, not just the client
        // area.
        wxSize newSize = event.GetSize();

        if (m_oldSize.x == wxDefaultCoord && m_oldSize.y == wxDefaultCoord)
        {
            m_oldSize = newSize;
            return;
        }

        if (HasFlag( wxSIMPLE_BORDER ))
        {
            if (newSize.y > m_oldSize.y)
            {
                wxRect rect;
                rect.x = 0;
                rect.width = m_oldSize.x;
                rect.y = m_oldSize.y-2;
                rect.height = 1;
                Refresh( true, &rect );
            }
            else if (newSize.y < m_oldSize.y)
            {
                wxRect rect;
                rect.y = newSize.y;
                rect.x = 0;
                rect.height = 1;
                rect.width = newSize.x;
                wxWindowNative::Refresh( true, &rect );
            }

            if (newSize.x > m_oldSize.x)
            {
                wxRect rect;
                rect.y = 0;
                rect.height = m_oldSize.y;
                rect.x = m_oldSize.x-2;
                rect.width = 1;
                Refresh( true, &rect );
            }
            else if (newSize.x < m_oldSize.x)
            {
                wxRect rect;
                rect.x = newSize.x;
                rect.y = 0;
                rect.width = 1;
                rect.height = newSize.y;
                wxWindowNative::Refresh( true, &rect );
            }
        }
        else
        if (HasFlag( wxSUNKEN_BORDER ) || HasFlag( wxRAISED_BORDER ))
        {
            if (newSize.y > m_oldSize.y)
            {
                wxRect rect;
                rect.x = 0;
                rect.width = m_oldSize.x;
                rect.y = m_oldSize.y-4;
                rect.height = 2;
                Refresh( true, &rect );
            }
            else if (newSize.y < m_oldSize.y)
            {
                wxRect rect;
                rect.y = newSize.y;
                rect.x = 0;
                rect.height = 2;
                rect.width = newSize.x;
                wxWindowNative::Refresh( true, &rect );
            }

            if (newSize.x > m_oldSize.x)
            {
                wxRect rect;
                rect.y = 0;
                rect.height = m_oldSize.y;
                rect.x = m_oldSize.x-4;
                rect.width = 2;
                Refresh( true, &rect );
            }
            else if (newSize.x < m_oldSize.x)
            {
                wxRect rect;
                rect.x = newSize.x;
                rect.y = 0;
                rect.width = 2;
                rect.height = newSize.y;
                wxWindowNative::Refresh( true, &rect );
            }
        }

        m_oldSize = newSize;
    }
#endif
}

wxSize wxWindow::DoGetBestSize() const
{
    return AdjustSize(DoGetBestClientSize());
}

wxSize wxWindow::DoGetBestClientSize() const
{
    return wxWindowNative::DoGetBestSize();
}

wxSize wxWindow::AdjustSize(const wxSize& size) const
{
    wxSize sz = size;
    if ( m_renderer )
        m_renderer->AdjustSize(&sz, this);
    return sz;
}

wxPoint wxWindow::GetClientAreaOrigin() const
{
    wxPoint pt = wxWindowBase::GetClientAreaOrigin();

#if wxUSE_TWO_WINDOWS
#else
    if ( m_renderer )
        pt += m_renderer->GetBorderDimensions(GetBorder()).GetPosition();
#endif

    return pt;
}

void wxWindow::DoGetClientSize(int *width, int *height) const
{
    // if it is a native window, we assume it handles the scrollbars itself
    // too - and if it doesn't, there is not much we can do
    if ( !m_renderer )
    {
        wxWindowNative::DoGetClientSize(width, height);

        return;
    }

    int w, h;
    wxWindowNative::DoGetClientSize(&w, &h);

    // we assume that the scrollbars are positioned correctly (by a previous
    // call to PositionScrollbars()) here

    wxRect rectBorder;
    if ( m_renderer )
        rectBorder = m_renderer->GetBorderDimensions(GetBorder());

    bool inside = m_renderer->AreScrollbarsInsideBorder();

    if ( width )
    {
        // in any case, take account of the scrollbar
        if ( m_scrollbarVert )
            w -= m_scrollbarVert->GetSize().x;

        // if we don't have scrollbar or if it is outside the border (and not
        // blended into it), take account of the right border as well
        if ( !m_scrollbarVert || inside )
            w -= rectBorder.width;

        // and always account for the left border
        *width = w - rectBorder.x;

        // we shouldn't return invalid width
        if ( *width < 0 )
            *width = 0;
    }

    if ( height )
    {
        if ( m_scrollbarHorz )
            h -= m_scrollbarHorz->GetSize().y;

        if ( !m_scrollbarHorz || inside )
            h -= rectBorder.height;

        *height = h - rectBorder.y;

        // we shouldn't return invalid height
        if ( *height < 0 )
            *height = 0;
    }
}

void wxWindow::DoSetClientSize(int width, int height)
{
    // take into account the borders
    wxRect rectBorder = m_renderer->GetBorderDimensions(GetBorder());
    width += rectBorder.x;
    height += rectBorder.y;

    // and the scrollbars (as they may be offset into the border, use the
    // scrollbar position, not size - this supposes that PositionScrollbars()
    // had been called before)
    bool inside = m_renderer->AreScrollbarsInsideBorder();
    wxSize size = GetSize();
    if ( m_scrollbarVert )
        width += size.x - m_scrollbarVert->GetPosition().x;
    if ( !m_scrollbarVert || inside )
        width += rectBorder.width;

    if ( m_scrollbarHorz )
        height += size.y - m_scrollbarHorz->GetPosition().y;
    if ( !m_scrollbarHorz || inside )
        height += rectBorder.height;

    wxWindowNative::DoSetClientSize(width, height);
}

wxHitTest wxWindow::DoHitTest(wxCoord x, wxCoord y) const
{
    wxHitTest ht = wxWindowNative::DoHitTest(x, y);
    if ( ht == wxHT_WINDOW_INSIDE )
    {
        if ( m_scrollbarVert && x >= m_scrollbarVert->GetPosition().x )
        {
            // it can still be changed below because it may also be the corner
            ht = wxHT_WINDOW_VERT_SCROLLBAR;
        }

        if ( m_scrollbarHorz && y >= m_scrollbarHorz->GetPosition().y )
        {
            ht = ht == wxHT_WINDOW_VERT_SCROLLBAR ? wxHT_WINDOW_CORNER
                                                  : wxHT_WINDOW_HORZ_SCROLLBAR;
        }
    }

    return ht;
}

// ----------------------------------------------------------------------------
// scrolling: we implement it entirely ourselves except for ScrollWindow()
// function which is supposed to be (efficiently) implemented by the native
// window class
// ----------------------------------------------------------------------------

void wxWindow::RefreshScrollbars()
{
    if ( m_scrollbarHorz )
        m_scrollbarHorz->Refresh();

    if ( m_scrollbarVert )
        m_scrollbarVert->Refresh();
}

void wxWindow::PositionScrollbars()
{
    // do not use GetClientSize/Rect as it relies on the scrollbars being
    // correctly positioned

    wxSize size = GetSize();
    wxBorder border = GetBorder();
    wxRect rectBorder = m_renderer->GetBorderDimensions(border);
    bool inside = m_renderer->AreScrollbarsInsideBorder();

    int height = m_scrollbarHorz ? m_scrollbarHorz->GetSize().y : 0;
    int width = m_scrollbarVert ? m_scrollbarVert->GetSize().x : 0;

    wxRect rectBar;
    if ( m_scrollbarVert )
    {
        rectBar.x = size.x - width;
        if ( inside )
           rectBar.x -= rectBorder.width;
        rectBar.width = width;
        rectBar.y = 0;
        if ( inside )
            rectBar.y += rectBorder.y;
        rectBar.height = size.y - height;
        if ( inside )
            rectBar.height -= rectBorder.y + rectBorder.height;

        m_scrollbarVert->SetSize(rectBar, wxSIZE_NO_ADJUSTMENTS);
    }

    if ( m_scrollbarHorz )
    {
        rectBar.y = size.y - height;
        if ( inside )
            rectBar.y -= rectBorder.height;
        rectBar.height = height;
        rectBar.x = 0;
        if ( inside )
            rectBar.x += rectBorder.x;
        rectBar.width = size.x - width;
        if ( inside )
            rectBar.width -= rectBorder.x + rectBorder.width;

        m_scrollbarHorz->SetSize(rectBar, wxSIZE_NO_ADJUSTMENTS);
    }

    RefreshScrollbars();
}

void wxWindow::SetScrollbar(int orient,
                            int pos,
                            int pageSize,
                            int range,
                            bool refresh)
{
    wxASSERT_MSG( pageSize <= range,
                    _T("page size can't be greater than range") );

    bool hasClientSizeChanged = false;
    wxScrollBar *scrollbar = GetScrollbar(orient);
    if ( range && (pageSize < range) )
    {
        if ( !scrollbar )
        {
            // create it
#if wxUSE_TWO_WINDOWS
            SetInsertIntoMain( true );
#endif
            scrollbar = new wxScrollBar(this, wxID_ANY,
                                        wxDefaultPosition, wxDefaultSize,
                                        orient & wxVERTICAL ? wxSB_VERTICAL
                                                            : wxSB_HORIZONTAL);
#if wxUSE_TWO_WINDOWS
            SetInsertIntoMain( false );
#endif
            if ( orient & wxVERTICAL )
                m_scrollbarVert = scrollbar;
            else
                m_scrollbarHorz = scrollbar;

            // the client area diminished as we created a scrollbar
            hasClientSizeChanged = true;

            PositionScrollbars();
        }
        else if ( GetWindowStyle() & wxALWAYS_SHOW_SB )
        {
            // we might have disabled it before
            scrollbar->Enable();
        }

        scrollbar->SetScrollbar(pos, pageSize, range, pageSize, refresh);
    }
    else // no range means no scrollbar
    {
        if ( scrollbar )
        {
            // wxALWAYS_SHOW_SB only applies to the vertical scrollbar
            if ( (orient & wxVERTICAL) && (GetWindowStyle() & wxALWAYS_SHOW_SB) )
            {
                // just disable the scrollbar
                scrollbar->SetScrollbar(pos, pageSize, range, pageSize, refresh);
                scrollbar->Disable();
            }
            else // really remove the scrollbar
            {
                delete scrollbar;

                if ( orient & wxVERTICAL )
                    m_scrollbarVert = NULL;
                else
                    m_scrollbarHorz = NULL;

                // the client area increased as we removed a scrollbar
                hasClientSizeChanged = true;

                // the size of the remaining scrollbar must be adjusted
                if ( m_scrollbarHorz || m_scrollbarVert )
                {

⌨️ 快捷键说明

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