📄 controlbar.cpp
字号:
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(); // bottom rect's y rect.height = rect.y - curY; rect.x = curX; rect.y = curY; rect.width = wxMin( paneHeight, frmWidth ); pPane->SetBoundsInParent( rect ); curX += rect.width; // setup RIGHT pane pPane = mPanes[ FL_ALIGN_RIGHT ]; // left pane's height pPane->SetPaneWidth( rect.height ); pPane->RecalcLayout(); paneHeight = pPane->GetPaneHeight(); // left pane's height rect.height = rect.height; rect.x = wxMax( frmWidth - paneHeight, curX ); rect.y = curY; rect.width = frmWidth - rect.x; pPane->SetBoundsInParent( rect ); // recalc bounds of the client-window mClntWndBounds.x = mPanes[FL_ALIGN_LEFT]->mBoundsInParent.x + mPanes[FL_ALIGN_LEFT]->mBoundsInParent.width; mClntWndBounds.y = mPanes[FL_ALIGN_TOP ]->mBoundsInParent.y + mPanes[FL_ALIGN_TOP ]->mBoundsInParent.height; mClntWndBounds.width = mPanes[FL_ALIGN_RIGHT]->mBoundsInParent.x - mClntWndBounds.x; mClntWndBounds.height = mPanes[FL_ALIGN_BOTTOM]->mBoundsInParent.y - mClntWndBounds.y; if ( repositionBarsNow ) PositionPanes();}int wxFrameLayout::GetClientHeight(){ // for better portablility wxWindow::GetSzie() is not used here return mClntWndBounds.height;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -