📄 rowlayoutpl.cpp
字号:
return maxHeight;}void cbRowLayoutPlugin::StickRightSideBars( cbBarInfo* pToBar ){ cbBarInfo* pBar = pToBar->mpNext; cbBarInfo* pPrev = pToBar; while( pBar ) { wxRect& cur = pBar->mBounds; wxRect& prev = pPrev->mBounds; cur.x = prev.x + prev.width; pPrev = pBar; pBar = pBar->mpNext; }}void cbRowLayoutPlugin::SlideLeftSideBars( cbBarInfo* pTheBar ){ // shift left-side-bars to the left (with respect to "theBar"), // so that they would not obscured by each other cbBarInfo* pBar = pTheBar->mpPrev; cbBarInfo* pPrev = pTheBar; while( pBar ) { wxRect& cur = pBar->mBounds; wxRect& prev = pPrev->mBounds; if ( cur.x + cur.width > prev.x ) cur.x = prev.x - cur.width; pPrev = pBar; pBar = pBar->mpPrev; }}void cbRowLayoutPlugin::SlideRightSideBars( cbBarInfo* pTheBar ){ // shift right-side-bars to the right (with respect to "theBar"), // so that they would not be obscured by each other cbBarInfo* pBar = pTheBar->mpNext; cbBarInfo* pPrev = pTheBar; while( pBar ) { wxRect& cur = pBar->mBounds; wxRect& prev = pPrev->mBounds; if ( cur.x < prev.x + prev.width ) cur.x = prev.x + prev.width; pPrev = pBar; pBar = pBar->mpNext; }}void cbRowLayoutPlugin::ShiftLeftTrashold( cbBarInfo* WXUNUSED(pTheBar), cbRowInfo& row ){ wxRect& first = row.mBars[0]->mBounds; if ( first.x < 0 ) { row.mBars[0]->mBounds.x = 0; SlideRightSideBars( row.mBars[0] ); }}void cbRowLayoutPlugin::ShiftRightTrashold( cbBarInfo* pTheBar, cbRowInfo& row ){ wxRect& theBar = pTheBar->mBounds; do { cbBarInfo* pBar = pTheBar; // calculate free spece on the left side int leftFreeSpc = 0; while( pBar ) { wxRect& cur = pBar->mBounds; if ( pBar->mpPrev ) { wxRect& prev = pBar->mpPrev->mBounds; leftFreeSpc += cur.x - prev.x - prev.width; } else leftFreeSpc += cur.x; if ( cur.x < 0 ) { leftFreeSpc = 0; break; } pBar = pBar->mpPrev; } pBar = pTheBar; int rightOverflow = 0; if ( pTheBar->IsFixed() ) while( pBar ) { if ( !pBar->mpNext ) { wxRect& cur = pBar->mBounds; if ( cur.x + cur.width > mpPane->mPaneWidth ) rightOverflow = cur.x + cur.width - mpPane->mPaneWidth; } pBar = pBar->mpNext; } if ( rightOverflow > 0 ) { if ( leftFreeSpc <= 0 ) return; if ( pTheBar->mpNext ) { wxRect& next = pTheBar->mpNext->mBounds; // if there's enough space on the left, move over one half-obscured // bar from the right to the left side with respect to "theBar" if ( next.width < leftFreeSpc ) { cbBarInfo* pNext = pTheBar->mpNext; row.mBars.Remove( pNext ); row.mBars.Insert( pNext, row.mBars.Index( pTheBar ) ); next.x = theBar.x - next.width; // re-setup mpPrev/mpNext references after insertion mpPane->InitLinksForRow( &row ); // tighten things StickRightSideBars( pTheBar ); SlideLeftSideBars ( pTheBar ); continue; } } int leftShift = ( rightOverflow > leftFreeSpc ) ? leftFreeSpc : rightOverflow; theBar.x -= leftShift; StickRightSideBars( pTheBar ); SlideLeftSideBars ( pTheBar ); break; } // end of if ( rightOverflow ) else break; } while(1);}void cbRowLayoutPlugin::InsertBefore( cbBarInfo* pBeforeBar, cbBarInfo* pTheBar, cbRowInfo& row ){ if ( pBeforeBar ) row.mBars.Insert( pTheBar, row.mBars.Index( pBeforeBar ) ); else row.mBars.Add( pTheBar ); pTheBar->mpRow = &row;}void cbRowLayoutPlugin::DoInsertBar( cbBarInfo* pTheBar, cbRowInfo& row ){ wxRect& theBar = pTheBar->mBounds; /* OLD STUFF:: if ( theBar.x < 0 && !node_to_bar( pTheBar ).IsFixed() ) { // AI:: theBar.width += theBar.x; theBar.x = 0; } */ size_t i; for ( i = 0; i != row.mBars.Count(); ++i ) { cbBarInfo& bar = *row.mBars[i]; wxRect& cur = bar.mBounds; // if bar hits the left edge if ( theBar.x <= cur.x ) { InsertBefore( &bar, pTheBar, row ); return; } else // if bar hits the right edge if ( theBar.x <= cur.x + cur.width ) { if ( theBar.x + theBar.width > cur.x + cur.width ) { InsertBefore( bar.mpNext, pTheBar, row ); return; } // otherwise the bar lies within the bounds of current bar int leftDist = theBar.x - cur.x; int rightDist = cur.x + cur.width - (theBar.x + theBar.width); if ( leftDist < rightDist ) InsertBefore( &bar, pTheBar, row ); else InsertBefore( bar.mpNext, pTheBar, row ); return; } } InsertBefore( NULL, pTheBar, row ); // insert at the end}// evnet handlersvoid cbRowLayoutPlugin::OnInsertBar( cbInsertBarEvent& event ){ cbBarInfo* pBarToInsert = event.mpBar; cbRowInfo* pIntoRow = event.mpRow; mpPane = event.mpPane; if ( !pBarToInsert->IsFixed() ) AdjustLengthOfInserted( pIntoRow, pBarToInsert ); DoInsertBar( pBarToInsert, *pIntoRow ); mpPane->InitLinksForRow( pIntoRow ); // relink "mpNext/mpPrev"s // perform relayouting of the bars after insertion // init bar location info pBarToInsert->mAlignment = event.mpPane->mAlignment; pBarToInsert->mRowNo = event.mpPane->GetRowIndex( pIntoRow );#ifdef __EXPERIMENTAL if ( !pIntoRow->mHasOnlyFixedBars || !pBarToInsert->IsFixed() ) RecalcLengthRatios( pIntoRow );#endif MinimzeNotFixedBars( pIntoRow, pBarToInsert ); SlideLeftSideBars ( pBarToInsert ); SlideRightSideBars( pBarToInsert ); ShiftLeftTrashold ( pBarToInsert, *pIntoRow ); ShiftRightTrashold( pBarToInsert, *pIntoRow ); mpPane->SyncRowFlags( pIntoRow ); CheckIfAtTheBoundary( pBarToInsert, *pIntoRow ); if ( event.mpPane->IsHorizontal() ) pBarToInsert->mState = wxCBAR_DOCKED_HORIZONTALLY; else pBarToInsert->mState = wxCBAR_DOCKED_VERTICALLY; if ( !pIntoRow->mHasOnlyFixedBars ) {#ifdef __EXPERIMENTAL ExpandNotFixedBars( pIntoRow );#else RelayoutNotFixedBarsAround( pBarToInsert, pIntoRow ); RecalcLengthRatios( pIntoRow );#endif DetectBarHandles( pIntoRow ); // do proportional resizing of not-fixed bars ApplyLengthRatios( pIntoRow ); } // adjust the bar's docking state // a little bit of AI: // memorize bar's height and width, when docked in // the current orientation - by making the current // dimensions to be "preferred" ones for this docking state if ( !pBarToInsert->IsFixed() ) { cbBarInfo& bar = *pBarToInsert; bar.mDimInfo.mSizes[ bar.mState ].x = bar.mBounds.width; bar.mDimInfo.mSizes[ bar.mState ].y = bar.mBounds.height; }}void cbRowLayoutPlugin::OnRemoveBar ( cbRemoveBarEvent& event ){ cbBarInfo* pBar = event.mpBar; mpPane = event.mpPane; cbRowInfo* pRow = pBar->mpRow; mpLayout->GetUpdatesManager().OnBarWillChange( pBar, pRow, event.mpPane ); // invalidate the whole row //pFirst->mpRowInfo->mMgrData.mPrevBounds.x = -1; pRow->mBars.Remove( pBar ); // rest bar information after removing it from the row pBar->mpRow = NULL; pBar->mHasLeftHandle = false; pBar->mHasRightHandle = false; mpPane->InitLinksForRow( pRow ); // relink "mpNext/mpPrev"s if ( pRow->mBars.Count() == 0 ) { // empty rows should not exist event.mpPane->GetRowList().Remove( pRow ); delete pRow; mpPane->InitLinksForRows(); } else { // force repainting of bars, in the row, from which the bar was removed // FIXME:: really needed? pRow->mBars[0]->mUMgrData.SetDirty(true); // re-setup mHasOnlyFixedBars flag for the row information event.mpPane->SyncRowFlags( pRow ); DetectBarHandles( pRow ); if ( !pRow->mHasOnlyFixedBars ) ExpandNotFixedBars( pRow ); }}void cbRowLayoutPlugin::OnLayoutRow( cbLayoutRowEvent& event ){ cbRowInfo* pRow = event.mpRow; mpPane = event.mpPane; MinimzeNotFixedBars( pRow, NULL ); if ( !pRow->mHasOnlyFixedBars ) { // do proportional resizing of not-fixed bars ApplyLengthRatios( pRow ); } cbBarInfo& lastBar = *pRow->mBars[ pRow->mBars.Count() - 1 ]; cbBarInfo& firstBar = *pRow->mBars[ 0 ]; // FIXME:: Next line not used // wxRect& bounds = lastBar.mBounds; if ( lastBar.mBounds.x + lastBar.mBounds.width > mpPane->mPaneWidth ) { lastBar.mBounds.x = mpPane->mPaneWidth - lastBar.mBounds.width; // first simulate left-row-edge friction SlideLeftSideBars( &lastBar ); if ( firstBar.mBounds.x < 0 ) firstBar.mBounds.x = 0; // then left-row-edge function, though this // may cause some of the right-side bars going // out of row bounds, but left-side always // has the highest "priority" SlideRightSideBars( &firstBar ); } event.Skip(); // pass event to the next handler}void cbRowLayoutPlugin::OnLayoutRows( cbLayoutRowsEvent& event ){ mpPane = event.mpPane; int curY = 0; // FIXME:: Next line not used. // RowArrayT& arr = mpPane->GetRowList(); size_t i; for ( i = 0; i != mpPane->GetRowList().Count(); ++i ) { cbRowInfo& row = *mpPane->GetRowList()[ i ]; //mpPane->CalcLengthRatios(& row); // setup "has-handle" flags for rows, which depend on the existence // of not-fixed bars in the row if ( !row.mHasOnlyFixedBars ) { if ( mpPane->mAlignment == FL_ALIGN_TOP || mpPane->mAlignment == FL_ALIGN_LEFT ) { row.mHasLowerHandle = true; row.mHasUpperHandle = false; } else { row.mHasUpperHandle = true; row.mHasLowerHandle = false; } } else { // otherwise, rows with fixed-bars only, have no height-resizing handles row.mHasUpperHandle = false; row.mHasLowerHandle = false; } // setup vertical positions for items in the row row.mRowY = curY; row.mRowWidth = mpPane->mPaneWidth; row.mRowHeight = CalcRowHeight( row ); LayoutItemsVertically( row ); if ( row.mHasUpperHandle ) row.mRowHeight += mpPane->mProps.mResizeHandleSize; if ( row.mHasLowerHandle ) row.mRowHeight += mpPane->mProps.mResizeHandleSize; curY += row.mRowHeight; } event.Skip(); // pass event to the next handler - other hookeds plugin // may also add some "refinements" to the layout now}void cbRowLayoutPlugin::OnResizeRow( cbResizeRowEvent& event ){ // extract resize-event info int ofs = event.mHandleOfs; bool forUpperHandle = event.mForUpperHandle; cbRowInfo* pTheRow = event.mpRow; mpPane = event.mpPane; // FIXME:: Next line not used. //int newHeight = pTheRow->mRowHeight; if ( forUpperHandle ) { // calculate available free space from above, // which can be obtained by squeezing not-fixed height rows cbRowInfo* pRow = pTheRow->mpPrev; while( pRow ) { pRow = pRow->mpPrev; } } else { // calculate available free space from below, // which can be obtained by squeezing not-fixed height rows cbRowInfo* pRow = pTheRow->mpNext; while( pRow ) { pRow = pRow->mpNext; } } mpLayout->GetUpdatesManager().OnStartChanges(); int clientSize; // allow user adjusting pane vs. client-area space, for upper-handle if ( mpPane->IsHorizontal() ) clientSize = mpLayout->GetClientHeight(); else clientSize = mpLayout->GetClientWidth(); if ( forUpperHandle && ofs < -clientSize ) { int needed = -(ofs + clientSize); cbRowInfo* pRow = mpPane->GetRowList()[ 0 ]; // start squeezing rows from the top row towards bottom while( pRow != pTheRow && needed ) { // only not-fixed rows can be squeezed if ( !pRow->mHasOnlyFixedBars ) { int prevHeight = pRow->mRowHeight; int newHeight = wxMax( event.mpPane->GetMinimalRowHeight( pRow ), prevHeight - needed ); if ( newHeight != prevHeight ) { event.mpPane->SetRowHeight( pRow, newHeight ); needed -= prevHeight - pRow->mRowHeight; } } pRow = pRow->mpNext; } } // allow user adjusting pane vs. client-area space, for lower-handle if ( !forUpperHandle && ofs > clientSize ) { int needed = ofs - clientSize; cbRowInfo* pRow = mpPane->GetRowList()[ mpPane->GetRowList().Count() - 1 ]; // start squeezing rows from the bottom towards the top row while( pRow && needed ) { // only not-fixed rows can be squeezed if ( !pRow->mHasOnlyFixedBars ) { int prevHeight = pRow->mRowHeight; int newHeight = wxMax( event.mpPane->GetMinimalRowHeight( pRow ), prevHeight - needed ); if ( newHeight != prevHeight ) { event.mpPane->SetRowHeight( pRow, newHeight ); needed -= prevHeight - pRow->mRowHeight; } } pRow = pRow->mpPrev; } } if ( forUpperHandle ) event.mpPane->SetRowHeight( pTheRow, pTheRow->mRowHeight + (-ofs) ); else event.mpPane->SetRowHeight( pTheRow, pTheRow->mRowHeight + ofs ); mpLayout->RecalcLayout(false); mpLayout->GetUpdatesManager().OnFinishChanges(); mpLayout->GetUpdatesManager().UpdateNow();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -