topluniv.cpp

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

CPP
932
字号

    else if ( m_data.m_flags & wxINTERACTIVE_RESIZE )
    {
        wxPoint diff = wxGetMousePosition() - m_data.m_pos;
        m_data.m_rect = m_data.m_rectOrig;
        wxApplyResize(m_data, diff);
        m_data.m_window->SetSize(m_data.m_rect);
    }
}

void wxInteractiveMoveHandler::OnMouseDown(wxMouseEvent& WXUNUSED(event))
{
    if ( m_data.m_flags & wxINTERACTIVE_WAIT_FOR_INPUT )
    {
        m_data.m_evtLoop->Exit();
    }
}

void wxInteractiveMoveHandler::OnKeyDown(wxKeyEvent& event)
{
    wxPoint diff(wxDefaultCoord,wxDefaultCoord);
    
    switch ( event.GetKeyCode() )
    {
        case WXK_UP:    diff = wxPoint(0, -16); break;
        case WXK_DOWN:  diff = wxPoint(0, 16);  break;
        case WXK_LEFT:  diff = wxPoint(-16, 0); break;
        case WXK_RIGHT: diff = wxPoint(16, 0);  break;
        case WXK_ESCAPE:
            m_data.m_window->SetSize(m_data.m_rectOrig);
            m_data.m_evtLoop->Exit();
            return;
        case WXK_RETURN:
            m_data.m_evtLoop->Exit();
            return;
    }
    
    if ( diff.x != wxDefaultCoord )
    {
        if ( m_data.m_flags & wxINTERACTIVE_WAIT_FOR_INPUT )
        {
            m_data.m_flags &= ~wxINTERACTIVE_WAIT_FOR_INPUT;
            if ( m_data.m_sizingCursor )
            {
                wxEndBusyCursor();
                m_data.m_sizingCursor = false;
            }

            if ( m_data.m_flags & wxINTERACTIVE_MOVE )
            {
                m_data.m_pos = m_data.m_window->GetPosition() + 
                               wxPoint(m_data.m_window->GetSize().x/2, 8);
            }
        }

        wxPoint warp;
        bool changeCur = false;
        
        if ( m_data.m_flags & wxINTERACTIVE_MOVE )
        {
            m_data.m_rect.Offset(diff);
            m_data.m_window->Move(m_data.m_rect.GetPosition());
            warp = wxPoint(m_data.m_window->GetSize().x/2, 8);
        }
        else /* wxINTERACTIVE_RESIZE */
        {
            if ( !(m_data.m_flags & 
                  (wxINTERACTIVE_RESIZE_N | wxINTERACTIVE_RESIZE_S)) )
            {
                if ( diff.y < 0 )
                {
                    m_data.m_flags |= wxINTERACTIVE_RESIZE_N;
                    m_data.m_pos.y = m_data.m_window->GetPosition().y;
                    changeCur = true;
                }
                else if ( diff.y > 0 )
                {
                    m_data.m_flags |= wxINTERACTIVE_RESIZE_S;
                    m_data.m_pos.y = m_data.m_window->GetPosition().y +
                                     m_data.m_window->GetSize().y;
                    changeCur = true;
                }
            }
            if ( !(m_data.m_flags & 
                  (wxINTERACTIVE_RESIZE_W | wxINTERACTIVE_RESIZE_E)) )
            {
                if ( diff.x < 0 )
                {
                    m_data.m_flags |= wxINTERACTIVE_RESIZE_W;
                    m_data.m_pos.x = m_data.m_window->GetPosition().x;
                    changeCur = true;
                }
                else if ( diff.x > 0 )
                {
                    m_data.m_flags |= wxINTERACTIVE_RESIZE_E;
                    m_data.m_pos.x = m_data.m_window->GetPosition().x +
                                     m_data.m_window->GetSize().x;
                    changeCur = true;
                }
            }

            wxApplyResize(m_data, diff);
            m_data.m_window->SetSize(m_data.m_rect);

            if ( m_data.m_flags & wxINTERACTIVE_RESIZE_W )
                warp.x = 0;
            else if ( m_data.m_flags & wxINTERACTIVE_RESIZE_E )
                warp.x = m_data.m_window->GetSize().x-1;
            else
                warp.x = wxGetMousePosition().x - m_data.m_window->GetPosition().x;

            if ( m_data.m_flags & wxINTERACTIVE_RESIZE_N )
                warp.y = 0;
            else if ( m_data.m_flags & wxINTERACTIVE_RESIZE_S )
                warp.y = m_data.m_window->GetSize().y-1;
            else
                warp.y = wxGetMousePosition().y - m_data.m_window->GetPosition().y;
        }

        warp -= m_data.m_window->GetClientAreaOrigin();
        m_data.m_window->WarpPointer(warp.x, warp.y);

        if ( changeCur )
        {
            long hit = m_data.m_window->HitTest(warp);
            wxCursor cur;
            if ( wxGetResizingCursor(hit, cur) )
            {
                if ( m_data.m_sizingCursor )
                    wxEndBusyCursor();
                wxBeginBusyCursor(&cur);
                m_data.m_sizingCursor = true;
            }
        }
    }
}

void wxInteractiveMoveHandler::OnMouseUp(wxMouseEvent& WXUNUSED(event))
{
    m_data.m_evtLoop->Exit();
}


void wxTopLevelWindow::InteractiveMove(int flags)
{
    wxASSERT_MSG( !((flags & wxINTERACTIVE_MOVE) && (flags & wxINTERACTIVE_RESIZE)),
                  wxT("can't move and resize window at the same time") );

    wxASSERT_MSG( !(flags & wxINTERACTIVE_RESIZE) || 
                  (flags & wxINTERACTIVE_WAIT_FOR_INPUT) || 
                  (flags & wxINTERACTIVE_RESIZE_DIR),
                  wxT("direction of resizing not specified") );

    wxInteractiveMoveData data;
    wxEventLoop loop;
    
    SetFocus();

#ifndef __WXGTK__    
    if ( flags & wxINTERACTIVE_WAIT_FOR_INPUT )
    {
        wxCursor sizingCursor(wxCURSOR_SIZING);
        wxBeginBusyCursor(&sizingCursor);
        data.m_sizingCursor = true;
    }
    else
#endif
        data.m_sizingCursor = false;

    data.m_window = this;
    data.m_evtLoop = &loop;
    data.m_flags = flags;
    data.m_rect = data.m_rectOrig = GetRect();
    data.m_pos = wxGetMousePosition();
    data.m_minSize = wxSize(GetMinWidth(), GetMinHeight());
    data.m_maxSize = wxSize(GetMaxWidth(), GetMaxHeight());

    wxEvtHandler *handler = new wxInteractiveMoveHandler(data);
    this->PushEventHandler(handler);

    CaptureMouse();
    loop.Run();
    ReleaseMouse();

    this->RemoveEventHandler(handler);
    delete handler;

    if ( data.m_sizingCursor )
        wxEndBusyCursor();
}

// ----------------------------------------------------------------------------
// actions
// ----------------------------------------------------------------------------

void wxTopLevelWindow::ClickTitleBarButton(long button)
{
    switch ( button )
    {
        case wxTOPLEVEL_BUTTON_CLOSE:
            Close();
            break;

        case wxTOPLEVEL_BUTTON_ICONIZE:
            Iconize();
            break;

        case wxTOPLEVEL_BUTTON_MAXIMIZE:
            Maximize();
            break;

        case wxTOPLEVEL_BUTTON_RESTORE:
            Restore();
            break;

        case wxTOPLEVEL_BUTTON_HELP:
#if wxUSE_HELP
            {
            wxContextHelp contextHelp(this);
            }
#endif
            break;

        default:
            wxFAIL_MSG(wxT("incorrect button specification"));
    }
}

bool wxTopLevelWindow::PerformAction(const wxControlAction& action,
                                     long numArg,
                                     const wxString& WXUNUSED(strArg))
{
    bool isActive = numArg != 0;

    if ( action == wxACTION_TOPLEVEL_ACTIVATE )
    {
        if ( m_isActive != isActive )
        {
            m_isActive = isActive;
            RefreshTitleBar();
        }
        return true;
    }

    else if ( action == wxACTION_TOPLEVEL_BUTTON_PRESS )
    {
        m_pressedButton = numArg;
        RefreshTitleBar();
        return true;
    }

    else if ( action == wxACTION_TOPLEVEL_BUTTON_RELEASE )
    {
        m_pressedButton = 0;
        RefreshTitleBar();
        return true;
    }

    else if ( action == wxACTION_TOPLEVEL_BUTTON_CLICK )
    {
        m_pressedButton = 0;
        RefreshTitleBar();
        ClickTitleBarButton(numArg);
        return true;
    }

    else if ( action == wxACTION_TOPLEVEL_MOVE )
    {
        InteractiveMove(wxINTERACTIVE_MOVE);
        return true;
    }

    else if ( action == wxACTION_TOPLEVEL_RESIZE )
    {
        int flags = wxINTERACTIVE_RESIZE;
        if ( numArg & wxHT_TOPLEVEL_BORDER_N )
            flags |= wxINTERACTIVE_RESIZE_N;
        if ( numArg & wxHT_TOPLEVEL_BORDER_S )
            flags |= wxINTERACTIVE_RESIZE_S;
        if ( numArg & wxHT_TOPLEVEL_BORDER_W )
            flags |= wxINTERACTIVE_RESIZE_W;
        if ( numArg & wxHT_TOPLEVEL_BORDER_E )
            flags |= wxINTERACTIVE_RESIZE_E;
        InteractiveMove(flags);
        return true;
    }

    else
        return false;
}

void wxTopLevelWindow::OnSystemMenu(wxCommandEvent& event)
{
    bool ret = true;
    
    switch (event.GetId())
    {
        case wxID_CLOSE_FRAME:
            ret = PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK,
                                wxTOPLEVEL_BUTTON_CLOSE);
            break;
        case wxID_MOVE_FRAME:
            InteractiveMove(wxINTERACTIVE_MOVE | wxINTERACTIVE_WAIT_FOR_INPUT);
            break;
        case wxID_RESIZE_FRAME:
            InteractiveMove(wxINTERACTIVE_RESIZE | wxINTERACTIVE_WAIT_FOR_INPUT);
            break;
        case wxID_MAXIMIZE_FRAME:
            ret = PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK,
                                wxTOPLEVEL_BUTTON_MAXIMIZE);
            break;
        case wxID_ICONIZE_FRAME:
            ret = PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK,
                                wxTOPLEVEL_BUTTON_ICONIZE);
            break;
        case wxID_RESTORE_FRAME:
            ret = PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK,
                                wxTOPLEVEL_BUTTON_RESTORE);
            break;

        default:
            ret = false;
    }
    
    if ( !ret )
        event.Skip();
}


// ============================================================================
// wxStdFrameInputHandler: handles focus, resizing and titlebar buttons clicks
// ============================================================================

wxStdFrameInputHandler::wxStdFrameInputHandler(wxInputHandler *inphand)
            : wxStdInputHandler(inphand)
{
    m_winCapture = NULL;
    m_winHitTest = 0;
    m_winPressed = 0;
    m_borderCursorOn = false;
}

bool wxStdFrameInputHandler::HandleMouse(wxInputConsumer *consumer,
                                         const wxMouseEvent& event)
{
    // the button has 2 states: pressed and normal with the following
    // transitions between them:
    //
    //      normal -> left down -> capture mouse and go to pressed state
    //      pressed -> left up inside -> generate click -> go to normal
    //                         outside ------------------>
    //
    // the other mouse buttons are ignored
    if ( event.Button(1) )
    {
        if ( event.ButtonDown(1) )
        {
            wxTopLevelWindow *w = wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow);
            long hit = w->HitTest(event.GetPosition());

            if ( hit & wxHT_TOPLEVEL_ANY_BUTTON )
            {
                m_winCapture = w;
                m_winCapture->CaptureMouse();
                m_winHitTest = hit;
                m_winPressed = hit;
                consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS, m_winPressed);
                return true;
            }
            else if ( (hit & wxHT_TOPLEVEL_TITLEBAR) && !w->IsMaximized() )
            {
                consumer->PerformAction(wxACTION_TOPLEVEL_MOVE);
                return true;
            }
            else if ( (consumer->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER)
                      && (hit & wxHT_TOPLEVEL_ANY_BORDER) )
            {
                consumer->PerformAction(wxACTION_TOPLEVEL_RESIZE, hit);
                return true;
            }
        }

        else // up
        {
            if ( m_winCapture )
            {
                m_winCapture->ReleaseMouse();
                m_winCapture = NULL;

                if ( m_winHitTest == m_winPressed )
                {
                    consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK, m_winPressed);
                    return true;
                }
            }
            //else: the mouse was released outside the window, this doesn't
            //      count as a click
        }
    }

    return wxStdInputHandler::HandleMouse(consumer, event);
}

bool wxStdFrameInputHandler::HandleMouseMove(wxInputConsumer *consumer,
                                             const wxMouseEvent& event)
{
    if ( event.GetEventObject() == m_winCapture )
    {
        long hit = m_winCapture->HitTest(event.GetPosition());

        if ( hit != m_winHitTest )
        {
            if ( hit != m_winPressed )
                consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_RELEASE, m_winPressed);
            else
                consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS, m_winPressed);

            m_winHitTest = hit;
            return true;
        }
    }
    else if ( consumer->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER )
    {
        wxTopLevelWindow *win = wxStaticCast(consumer->GetInputWindow(),
                                             wxTopLevelWindow);
        long hit = win->HitTest(event.GetPosition());

        if ( hit != m_winHitTest )
        {
            m_winHitTest = hit;

            if ( m_borderCursorOn )
            {
                m_borderCursorOn = false;
                win->SetCursor(m_origCursor);
            }

            if ( hit & wxHT_TOPLEVEL_ANY_BORDER )
            {
                wxCursor cur;

                m_borderCursorOn = wxGetResizingCursor(hit, cur);
                if ( m_borderCursorOn )
                {
                    m_origCursor = win->GetCursor();
                    win->SetCursor(cur);
                }
            }
        }
    }

    return wxStdInputHandler::HandleMouseMove(consumer, event);
}

bool wxStdFrameInputHandler::HandleActivation(wxInputConsumer *consumer,
                                              bool activated)
{
    if ( m_borderCursorOn )
    {
        consumer->GetInputWindow()->SetCursor(m_origCursor);
        m_borderCursorOn = false;
    }
    consumer->PerformAction(wxACTION_TOPLEVEL_ACTIVATE, activated);
    return false;
}

⌨️ 快捷键说明

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