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

📄 controlbar.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    return mpFrameClient;
}

cbUpdatesManagerBase& wxFrameLayout::GetUpdatesManager()
{
    if ( !mpUpdatesMgr )
        mpUpdatesMgr = CreateUpdatesManager();

    return *mpUpdatesMgr;
}

void wxFrameLayout::SetUpdatesManager( cbUpdatesManagerBase* pUMgr )
{
    if ( mpUpdatesMgr )
        delete mpUpdatesMgr;

    mpUpdatesMgr = pUMgr;

    mpUpdatesMgr->SetLayout( this );
}

cbUpdatesManagerBase* wxFrameLayout::CreateUpdatesManager()
{
    return new cbGCUpdatesMgr( this );
    //return new cbSimpleUpdatesMgr( this );
}

void wxFrameLayout::AddBar( wxWindow*        pBarWnd,
                            const cbDimInfo& dimInfo,
                            int              alignment,
                            int              rowNo,
                            int              columnPos,
                            const wxString&  name,
                            bool             spyEvents,
                            int              state
                          )
{
    if ( pBarWnd && spyEvents )
    {
        // hook up spy to bar window
        cbBarSpy* pSpy = new cbBarSpy( this );

        pSpy->SetBarWindow( pBarWnd );
        pBarWnd->PushEventHandler( pSpy );

        mBarSpyList.Append( pSpy );
    }

    cbBarInfo* pInfo = new cbBarInfo();

    pInfo->mName      = name;
    pInfo->mpBarWnd   = pBarWnd;
    pInfo->mDimInfo   = dimInfo;
    pInfo->mDimInfo.mLRUPane = alignment;
    pInfo->mState     = state;
    pInfo->mAlignment = alignment;
    pInfo->mRowNo     = rowNo;
    pInfo->mBounds.x  = columnPos;

    mAllBars.Add( pInfo );

    DoSetBarState( pInfo );
}

bool wxFrameLayout::RedockBar( cbBarInfo*    pBar,
                               const wxRect& shapeInParent,
                               cbDockPane*   pToPane,
                               bool          updateNow )
{
    if ( !pToPane )

        pToPane = HitTestPanes( shapeInParent, NULL );

    if ( !pToPane )

        return false; // bar's shape does not hit any pane
                     // - redocking is NOT possible

    cbDockPane* pBarPane = GetBarPane( pBar );

    if ( updateNow )

        GetUpdatesManager().OnStartChanges();

    pBarPane->RemoveBar( pBar );

    // FIXME FIXME:: the recalculation below may be a *huge* performance
    //               hit, it could be eliminated though...
    //               but first the "pane-postion-changed" problem
    //               has to be fixed

    RecalcLayout( false );

    pToPane->InsertBar( pBar, shapeInParent );

    RecalcLayout( false );

    // finish update "transaction"

    if ( updateNow )
    {
        GetUpdatesManager().OnFinishChanges();
        GetUpdatesManager().UpdateNow();
    }

    return true;
}

cbBarInfo* wxFrameLayout::FindBarByName( const wxString& name )
{
    size_t i;
    for ( i = 0; i != mAllBars.Count(); ++i )
        if ( mAllBars[i]->mName == name )
            return mAllBars[i];

    return NULL;
}

cbBarInfo* wxFrameLayout::FindBarByWindow( const wxWindow* pWnd )
{
    size_t i;
    for ( i = 0; i != mAllBars.Count(); ++i )
        if ( mAllBars[i]->mpBarWnd == pWnd )
            return mAllBars[i];

    return NULL;
}

BarArrayT& wxFrameLayout::GetBars()
{
    return mAllBars;
}

void wxFrameLayout::SetBarState( cbBarInfo* pBar, int newState, bool updateNow )
{
    if ( newState == wxCBAR_FLOATING && !(mFloatingOn && pBar->mFloatingOn))

        return;

    if ( updateNow )

        GetUpdatesManager().OnStartChanges();

    pBar->mUMgrData.SetDirty(true);

    // check bar's previous state

    if ( pBar->mState != wxCBAR_HIDDEN && pBar->mState != wxCBAR_FLOATING )
    {
        cbDockPane* pPane;
        cbRowInfo*  pRow;

        #ifdef  __WXDEBUG__
        bool success =
        #endif
                       LocateBar( pBar, &pRow, &pPane );

        wxASSERT( success ); // DBG::

        // save LRU-dim info before removing bar

        pBar->mDimInfo.mLRUPane = pPane->GetAlignment();
        pBar->mDimInfo.mBounds[ pPane->GetAlignment() ] = pBar->mBounds;

        // remove it from the pane it was docked on

        pPane->RemoveBar( pBar );

    }

    if ( pBar->mState == wxCBAR_FLOATING && newState != wxCBAR_FLOATING )
    {
        // remove bar's window from the containing mini-frame
        // and set its parent to be layout's parent frame

        if ( pBar->mpBarWnd )
        {
            pBar->mpBarWnd->Show(false); // to avoid flicker upon reparenting

            wxObjectList::compatibility_iterator pNode = mFloatedFrames.GetFirst();

            while( pNode )
            {
                cbFloatedBarWindow* pFFrm = ((cbFloatedBarWindow*)pNode->GetData());

                if ( pFFrm->GetBar() == pBar )
                {
                    pFFrm->Show( false ); // reduces flicker sligthly

                    ReparentWindow( pBar->mpBarWnd, &GetParentFrame() );

                    pBar->mBounds = pBar->mDimInfo.mBounds[ pBar->mDimInfo.mLRUPane ];

                    if ( newState != wxCBAR_HIDDEN )

                        pBar->mAlignment = pBar->mDimInfo.mLRUPane;

                    mFloatedFrames.Erase( pNode );

                    pFFrm->Show( false );
                    pFFrm->Destroy(); break;
                }

                pNode = pNode->GetNext();
            }

            // FOR NOW:: excessive!
            //if ( mpFrameClient ) mpFrameClient->Refresh();
            if ( mpFrameClient )
                mClientWndRefreshPending = true;
        }
    }

    if ( pBar->mDimInfo.GetDimHandler() )
    {
        pBar->mDimInfo.GetDimHandler()->OnChangeBarState( pBar, newState );
    }

    pBar->mState = newState;

    DoSetBarState( pBar );

    if ( updateNow )
    {
        RecalcLayout(false);

        GetUpdatesManager().OnFinishChanges();
        GetUpdatesManager().UpdateNow();
    }
}

void wxFrameLayout::InverseVisibility( cbBarInfo* pBar )
{
    wxASSERT( pBar ); // DBG::

    // "inverse" bar-visibility of the selected bar

    int newState;

    if ( pBar->mState == wxCBAR_HIDDEN )
    {
        if ( pBar->mAlignment == -1 )
        {
            pBar->mAlignment = 0;       // just remove "-1" marking
            newState = wxCBAR_FLOATING;
        }
        else
        if ( pBar->mAlignment == FL_ALIGN_TOP ||
             pBar->mAlignment == FL_ALIGN_BOTTOM )

            newState = wxCBAR_DOCKED_HORIZONTALLY;
        else
            newState = wxCBAR_DOCKED_VERTICALLY;
    }
    else
    {
        newState = wxCBAR_HIDDEN;

        if ( pBar->mState == wxCBAR_FLOATING )

            pBar->mAlignment = -1;
    }

    this->SetBarState( pBar, newState, true );

    if ( newState == wxCBAR_FLOATING )

        this->RepositionFloatedBar( pBar );
}

void wxFrameLayout::ApplyBarProperties( cbBarInfo* pBar )
{
    if ( pBar->mState == wxCBAR_FLOATING )
    {
        RepositionFloatedBar( pBar );
    }
    else
    if ( pBar->mState == wxCBAR_DOCKED_HORIZONTALLY ||
         pBar->mState == wxCBAR_DOCKED_VERTICALLY
       )
    {
        // FOR NOW:: nothing
    }

}

void wxFrameLayout::RepositionFloatedBar( cbBarInfo* pBar )
{
    if ( !(mFloatingOn && pBar->mFloatingOn)) return;

    wxObjectList::compatibility_iterator pNode = mFloatedFrames.GetFirst();

    while( pNode )
    {
        cbFloatedBarWindow* pFFrm = ((cbFloatedBarWindow*)pNode->GetData());

        if ( pFFrm->GetBar() == pBar )
        {
            wxRect& bounds = pBar->mDimInfo.mBounds[wxCBAR_FLOATING];

            int x = bounds.x,
                y = bounds.y;

            GetParentFrame().ClientToScreen( &x, &y );

            pFFrm->PositionFloatedWnd( x,y,
                                       bounds.width,
                                       bounds.height );

            break;
        }

        pNode = pNode->GetNext();
    }
}

void wxFrameLayout::DoSetBarState( cbBarInfo* pBar )
{
    if ( pBar->mState != wxCBAR_FLOATING &&
         pBar->mState != wxCBAR_HIDDEN )

        // dock it

        mPanes[pBar->mAlignment]->InsertBar( pBar );
    else
    if ( pBar->mState == wxCBAR_HIDDEN )
    {
        // hide it

        if ( pBar->mpBarWnd )

            pBar->mpBarWnd->Show( false );
    }
    else
    {
        if ( !(mFloatingOn && pBar->mFloatingOn) )
          return;

        // float it

        if ( pBar->mpBarWnd == NULL || !CanReparent() )
        {
            // FOR NOW:: just hide it

            if ( pBar->mpBarWnd )

                pBar->mpBarWnd->Show( false );

            pBar->mState = wxCBAR_HIDDEN;

            return;
        }

        cbFloatedBarWindow* pMiniFrm = new cbFloatedBarWindow();

        pMiniFrm->SetBar( pBar );
        pMiniFrm->SetLayout( this );

        pMiniFrm->Create( &GetParentFrame(), wxID_ANY, pBar->mName,
                          wxPoint( 50,50 ),
                          wxSize ( 0, 0  ),
                          wxFRAME_FLOAT_ON_PARENT |
                          wxNO_BORDER |
                          wxFRAME_NO_TASKBAR
                        );

        pMiniFrm->SetClient( pBar->mpBarWnd );

        ReparentWindow( pBar->mpBarWnd, pMiniFrm );

        mFloatedFrames.Append( pMiniFrm );

        wxRect& bounds = pBar->mDimInfo.mBounds[wxCBAR_FLOATING];

        // check if it wasn't floated anytime before

        if ( bounds.width == -1 )
        {
            wxRect& clntRect = GetClientRect();

            // adjust position into which the next floated bar will be placed

            if ( mNextFloatedWndPos.x + bounds.width > clntRect.width )

                mNextFloatedWndPos.x = mFloatingPosStep.x;

            if ( mNextFloatedWndPos.y + bounds.height > clntRect.height )

                mNextFloatedWndPos.y = mFloatingPosStep.y;

            bounds.x = mNextFloatedWndPos.x + clntRect.x;
            bounds.y = mNextFloatedWndPos.y + clntRect.y;

            bounds.width  = pBar->mDimInfo.mSizes[wxCBAR_FLOATING].x;
            bounds.height = pBar->mDimInfo.mSizes[wxCBAR_FLOATING].y;

            mNextFloatedWndPos.x += mFloatingPosStep.x;
            mNextFloatedWndPos.y += mFloatingPosStep.y;
        }

        pMiniFrm->Show( true );
        RepositionFloatedBar(pMiniFrm->GetBar());

        // FIXME:: this is excessive
        pBar->mpBarWnd->Show(true);
    }
}

void wxFrameLayout::RemoveBar( cbBarInfo* pBarInfo )
{
    // first, try to "guess" what was the perviouse state of the bar

    cbDockPane* pPane;
    cbRowInfo*  pRow;

    if ( LocateBar( pBarInfo, &pRow, &pPane ) )
    {
        // ...aha, bar was docked into one of the panes,
        // remove it from there

        pPane->RemoveBar( pBarInfo );
    }

    size_t i;
    for ( i = 0; i != mAllBars.Count(); ++i )
    {
        if ( mAllBars[i] == pBarInfo )
        {
#if wxCHECK_VERSION(2,3,2)
            mAllBars.RemoveAt(i);
#else
            mAllBars.Remove(i);
#endif
            if ( pBarInfo->mpBarWnd ) // hides it's window

                pBarInfo->mpBarWnd->Show( false );

            delete pBarInfo;

            return;
        }
    }
    wxFAIL_MSG(wxT("bar info should be present in the list of all bars of all panes"));
}

bool wxFrameLayout::LocateBar( cbBarInfo* pBarInfo,
                               cbRowInfo**  ppRow,
                               cbDockPane** ppPane )
{
    (*ppRow)  = NULL;
    (*ppPane) = NULL;

    int n;
    for ( n = 0; n != MAX_PANES; ++n )
    {
        wxBarIterator i( mPanes[n]->GetRowList() );

        while ( i.Next() )

            if ( &i.BarInfo() == pBarInfo )
            {
                (*ppPane) = mPanes[n];
                (*ppRow ) = &i.RowInfo();

                return true;
            }
    }

    return false;
}

void wxFrameLayout::RecalcLayout( bool repositionBarsNow )
{
    mRecalcPending = false;

    int frmWidth, frmHeight;
    mpFrame->GetClientSize( &frmWidth, &frmHeight );

    int curY = 0;
    int curX = 0;
    wxRect rect;

    // pane positioning priorities in decreasing order:
    // top, bottom, left, right

    // setup TOP pane

    cbDockPane* pPane = mPanes[ FL_ALIGN_TOP ];

    pPane->SetPaneWidth( frmWidth );
    pPane->RecalcLayout();

    int paneHeight = pPane->GetPaneHeight();

    rect.x      = curX;
    rect.y      = curY;
    rect.width  = frmWidth;
    rect.height = wxMin( paneHeight, frmHeight - curY );

    pPane->SetBoundsInParent( rect );

    curY += paneHeight;

    // setup BOTTOM pane

    pPane = mPanes[ FL_ALIGN_BOTTOM ];

    pPane->SetPaneWidth( frmWidth );
    pPane->RecalcLayout();

    paneHeight = pPane->GetPaneHeight();

    rect.x      = curX;
    rect.y      = wxMax( frmHeight - paneHeight, curY );
    rect.width  = frmWidth;
    rect.height = frmHeight - rect.y;

    pPane->SetBoundsInParent( rect );

    // setup LEFT pane

    pPane = mPanes[ FL_ALIGN_LEFT ];

                         // bottom pane's y
    pPane->SetPaneWidth( rect.y - curY );

    pPane->RecalcLayout();
    paneHeight = pPane->GetPaneHeight();

⌨️ 快捷键说明

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