📄 controlbar.cpp
字号:
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 + -