📄 rowdragpl.cpp
字号:
}
/*** helpers for drag&drop ***/
void cbRowDragPlugin::SetMouseCapture( bool captureOn )
{
if ( mCaptureIsOn == captureOn ) return;
if ( captureOn )
{
mpLayout->CaptureEventsForPane( mpPane );
mpLayout->CaptureEventsForPlugin( this );
}
else
{
mpLayout->ReleaseEventsFromPane( mpPane );
mpLayout->ReleaseEventsFromPlugin( this );
}
mCaptureIsOn = captureOn;
}
void cbRowDragPlugin::UnhighlightItemInFocus()
{
wxClientDC dc( &mpLayout->GetParentFrame() );
if ( mpRowInFocus )
DrawRowDragHint( mpRowInFocus, dc, false );
else
if ( mCollapsedIconInFocus != - 1 )
DrawCollapsedRowIcon( mCollapsedIconInFocus, dc, false );
}
void cbRowDragPlugin::ShowDraggedRow( int offset )
{
// create combined image of pane and dragged
// row on it, in the mpCombinedImage bitmap
if ( mpPane->IsHorizontal() )
{
if ( mInitialRowOfs + offset + mRowImgDim.y > mCombRect.y + mCombRect.height )
offset = mCombRect.y + mCombRect.height - mRowImgDim.y - mInitialRowOfs;
if ( mInitialRowOfs + offset < mCombRect.y )
offset = mCombRect.y - mInitialRowOfs;
int x, y = mInitialRowOfs + offset;
mpPane->FrameToPane( &x, &y );
mCurDragOfs = y;
}
else
{
if ( mInitialRowOfs + offset + mRowImgDim.x > mCombRect.x + mCombRect.width )
offset = mCombRect.x + mCombRect.width - mRowImgDim.x - mInitialRowOfs;
if ( mInitialRowOfs + offset < mCombRect.x )
offset = mCombRect.x - mInitialRowOfs;
int x = mInitialRowOfs + offset, y;
mpPane->FrameToPane( &x, &y );
mCurDragOfs = x;
}
wxMemoryDC rowImgDc;
rowImgDc.SelectObject ( *mpRowImage );
wxMemoryDC paneImgDc;
paneImgDc.SelectObject( *mpPaneImage );
wxMemoryDC combImgDc;
combImgDc.SelectObject( *mpCombinedImage );
combImgDc.Blit( 0,0, mCombRect.width, mCombRect.height,
&paneImgDc, 0,0, wxCOPY );
if ( mpPane->IsHorizontal() )
{
combImgDc.Blit( 0, mInitialRowOfs + offset - mCombRect.y,
mCombRect.width, mRowImgDim.y,
&rowImgDc, 0,0, wxCOPY );
}
else
{
combImgDc.Blit( mInitialRowOfs + offset - mCombRect.x,
0,
mRowImgDim.x, mCombRect.height,
&rowImgDc, 0,0, wxCOPY );
}
int scrX = mCombRect.x,
scrY = mCombRect.y;
mpLayout->GetParentFrame().ClientToScreen( &scrX, &scrY );
mpScrDc->Blit( scrX, scrY, mCombRect.width, mCombRect.height,
&combImgDc, 0,0, wxCOPY );
rowImgDc .SelectObject( wxNullBitmap );
paneImgDc.SelectObject( wxNullBitmap );
combImgDc.SelectObject( wxNullBitmap );
}
wxBitmap* cbRowDragPlugin::CaptureDCArea( wxDC& dc, wxRect& area )
{
wxBitmap* pBmp = new wxBitmap( int(area.width), int(area.height) );
wxMemoryDC mdc;
mdc.SelectObject( *pBmp );
mdc.Blit( 0,0, area.width, area.height, &dc, area.x, area.y, wxCOPY );
mdc.SelectObject( wxNullBitmap );
return pBmp;
}
void cbRowDragPlugin::PrepareForRowDrag()
{
wxRect rowBounds = mpRowInFocus->mBoundsInParent;
if ( mpPane->IsHorizontal() )
{
mCombRect = mpPane->mBoundsInParent;
mCombRect.x += mpPane->mLeftMargin - ROW_DRAG_HINT_WIDTH - 1;
mCombRect.y += mpPane->mTopMargin;
mCombRect.width -= mpPane->mLeftMargin + mpPane->mRightMargin - ROW_DRAG_HINT_WIDTH - 1 - 1;
mCombRect.height -= mpPane->mTopMargin + mpPane->mBottomMargin;
mCombRect.height += 2*rowBounds.height;
mCombRect.y -= rowBounds.height;
mInitialRowOfs = rowBounds.y;
rowBounds.y -= 1;
rowBounds.height += 2;
rowBounds.x = mCombRect.x;
rowBounds.width = mCombRect.width;
mRowImgDim.y = rowBounds.height;
}
else
{
mCombRect = mpPane->mBoundsInParent;
mCombRect.y += mpPane->mTopMargin - 1;
mCombRect.x += mpPane->mLeftMargin - 1;
;
mCombRect.height -= mpPane->mTopMargin + mpPane->mBottomMargin - ROW_DRAG_HINT_WIDTH - 1 - 1;
mCombRect.width -= mpPane->mLeftMargin + mpPane->mRightMargin;
mCombRect.width += 2*rowBounds.width;
mCombRect.x -= rowBounds.width;
mInitialRowOfs = rowBounds.x;
rowBounds.x -= 1;
rowBounds.width += 2;
rowBounds.y = mCombRect.y;
rowBounds.height = mCombRect.height;
mRowImgDim.x = rowBounds.width;
}
// output cobination results onto frame's client area
wxScreenDC::StartDrawingOnTop(&mpLayout->GetParentFrame());
mpScrDc = new wxScreenDC();
int x = mCombRect.x, y = mCombRect.y;
mpLayout->GetParentFrame().ClientToScreen( &x, &y );
wxRect scrRect = mCombRect;
scrRect.x = x;
scrRect.y = y;
mpPaneImage = CaptureDCArea( *mpScrDc, scrRect );
wxMemoryDC mdc;
mdc.SelectObject( *mpPaneImage );
mdc.SetDeviceOrigin( -mCombRect.x, -mCombRect.y );
DrawRectShade( rowBounds, mdc, -1, mpLayout->mGrayPen, mpLayout->mDarkPen );
DrawRectShade( rowBounds, mdc, 0, mpLayout->mLightPen, mpLayout->mBlackPen );
mpRowImage = CaptureDCArea( mdc, rowBounds );
// draw dark empty-row placeholder
DrawEmptyRow( mdc, rowBounds );
//DrawRectShade( rowBounds, mdc, 0, mpLayout->mGrayPen, mpLayout->mDarkPen );
DrawRectShade( rowBounds, mdc, -1, mpLayout->mGrayPen, mpLayout->mGrayPen );
mdc.SelectObject( wxNullBitmap );
mpCombinedImage = new wxBitmap( int(mCombRect.width), int(mCombRect.height) );
// show it for the first time
ShowDraggedRow( 0 );
}
void cbRowDragPlugin::DrawEmptyRow( wxDC& dc, wxRect& rowBounds )
{
wxBrush bkBrush( mpLayout->mDarkPen.GetColour(), wxSOLID );
// paint the "dark" empty-row placeholder
dc.SetBrush( bkBrush );
dc.SetPen ( mpLayout->mNullPen );
dc.DrawRectangle( rowBounds.x, rowBounds.y,
rowBounds.width+1, rowBounds.height+1 );
dc.SetBrush( wxNullBrush );
}
void cbRowDragPlugin::ShowPaneImage()
{
int scrX = 0, scrY = 0;
mpLayout->GetParentFrame().ClientToScreen( &scrX, &scrY );
wxMemoryDC mdc;
mdc.SelectObject( *mpPaneImage );
mpScrDc->Blit( mCombRect.x + scrX, mCombRect.y + scrY,
mCombRect.width, mCombRect.height,
&mdc, 0,0, wxCOPY );
mdc.SelectObject( wxNullBitmap );
}
void cbRowDragPlugin::FinishOnScreenDraw()
{
wxScreenDC::EndDrawingOnTop();
delete mpScrDc;
delete mpCombinedImage;
delete mpPaneImage;
delete mpRowImage;
mpScrDc = NULL;
mpCombinedImage = mpPaneImage = mpRowImage = NULL;
}
void cbRowDragPlugin::CollapseRow( cbRowInfo* pRow )
{
int iconCnt = GetHRowsCountForPane( mpPane );
mpLayout->GetUpdatesManager().OnStartChanges();
cbBarInfo* pBar = pRow->mBars[0];
int rowNo = 0;
cbRowInfo* pCur = pRow;
while( pCur->mpPrev ) { ++rowNo; pCur = pCur->mpPrev; }
while( pBar )
{
cbHiddenBarInfo* pHBInfo = new cbHiddenBarInfo();
pHBInfo->mpBar = pBar;
pHBInfo->mRowNo = rowNo;
pHBInfo->mIconNo = iconCnt;
pHBInfo->mAlignment = mpPane->mAlignment;
mHiddenBars.Append( (wxObject*) pHBInfo );
// hide it
if ( pBar->mpBarWnd )
pBar->mpBarWnd->Show( false );
pBar->mState = wxCBAR_HIDDEN;
cbBarInfo* pNext = pBar->mpNext;
pBar->mpRow = NULL;
pBar->mpNext = NULL;
pBar->mpPrev = NULL;
pBar = pNext;
}
mpPane->GetRowList().Remove( pRow );
mpPane->InitLinksForRows();
delete pRow;
SetPaneMargins();
mpLayout->RecalcLayout(false);
mpRowInFocus = NULL;
mpLayout->GetUpdatesManager().OnFinishChanges();
mpLayout->GetUpdatesManager().UpdateNow();
}
void cbRowDragPlugin::ExpandRow( int collapsedIconIdx )
{
mpLayout->GetUpdatesManager().OnStartChanges();
cbRowInfo* pNewRow = new cbRowInfo();
wxNode* pNode = mHiddenBars.GetFirst();
int rowNo = 0;
// move bars from internal list to the newly expanded row
while( pNode )
{
cbHiddenBarInfo* pHBInfo = (cbHiddenBarInfo*)pNode->GetData();
if ( pHBInfo->mAlignment == mpPane->mAlignment &&
pHBInfo->mIconNo == collapsedIconIdx )
{
rowNo = pHBInfo->mRowNo;
if ( pHBInfo->mpBar->mState == wxCBAR_HIDDEN )
{
pNewRow->mBars.Add( pHBInfo->mpBar );
pHBInfo->mpBar->mState = ( mpPane->IsHorizontal() )
? wxCBAR_DOCKED_HORIZONTALLY
: wxCBAR_DOCKED_VERTICALLY;
}
// remove bar info from internal list
wxNode* pNext = pNode->GetNext();
delete pHBInfo;
mHiddenBars.DeleteNode( pNode );
pNode = pNext;
}
else
{
// decrease incon numbers with higher indicies, since this
// row is now removed from the hidden-rows list
if ( pHBInfo->mIconNo > collapsedIconIdx &&
pHBInfo->mAlignment == mpPane->mAlignment )
--pHBInfo->mIconNo;
pNode = pNode->GetNext();
}
}
mpPane->InitLinksForRow( pNewRow );
// insert row into pane at it's original position
if ( pNewRow->mBars.GetCount() )
{
cbRowInfo* beforeRowNode = mpPane->GetRow( rowNo );
mpPane->InsertRow( pNewRow, beforeRowNode );
}
else
delete pNewRow;
SetPaneMargins();
mpLayout->RecalcLayout(false);
mCollapsedIconInFocus = -1;
mpLayout->GetUpdatesManager().OnFinishChanges();
mpLayout->GetUpdatesManager().UpdateNow();
/*
wxNode* pRowNode = mHiddenRows.Nth( collapsedIconIdx );
mpLayout->GetUpdatesManager().OnStartChanges();
// insert at the end of rows list
mpPane->InsertRow( pRowNode, NULL );
int success = mHiddenRows.DeleteNode( pRowNode );
// DBG::
wxASSERT( success );
SetPaneMargins();
mpLayout->RecalcLayout(false);
mCollapsedIconInFocus = -1;
mpLayout->GetUpdatesManager().OnFinishChanges();
mpLayout->GetUpdatesManager().UpdateNow();
*/
}
void cbRowDragPlugin::InsertDraggedRowBefore( cbRowInfo* pBeforeRow )
{
if ( mpRowInFocus != pBeforeRow &&
mpRowInFocus->mpNext != pBeforeRow
)
{
mpPane->GetRowList().Remove( mpRowInFocus );
mpPane->InsertRow( mpRowInFocus, pBeforeRow );
}
else
{
// otherwise, nothing has happned (row positions do not change)
//wxClientDC dc( &mpLayout->GetParentFrame() );
//mpPane->PaintRow( mpRowInFocus, dc );
//DrawRowDragHint( mpRowInFocus, dc, false );
}
}
bool cbRowDragPlugin::ItemIsInFocus()
{
return ( mpRowInFocus || mCollapsedIconInFocus != - 1 );
}
void cbRowDragPlugin::CheckPrevItemInFocus( cbRowInfo* pRow, int iconIdx )
{
wxClientDC dc( &mpLayout->GetParentFrame() );
if ( pRow != NULL && mpRowInFocus == pRow ) return;
if ( iconIdx != -1 && mCollapsedIconInFocus == iconIdx ) return;
UnhighlightItemInFocus();
if ( iconIdx != - 1 )
DrawCollapsedRowIcon( iconIdx, dc, true );
else
if ( pRow != NULL )
DrawRowDragHint( pRow, dc, true );
}
cbRowInfo* cbRowDragPlugin::GetFirstRow()
{
return ( mpPane->GetRowList().GetCount() )
? mpPane->GetRowList()[0]
: NULL;
}
/*** "hard-coded" metafile for NN-look ***/
void cbRowDragPlugin::DrawTrianUp( wxRect& inRect, wxDC& dc )
{
int xOfs = (inRect.width - ICON_TRIAN_WIDTH)/2;
wxBrush br( mTrianInnerColor, wxSOLID );
dc.SetBrush( br );
dc.SetPen( mpLayout->mBlackPen );
wxPoint points[3];
points[0].x = inRect.x + xOfs;
points[0].y = inRect.y + inRect.height - 1;
points[1].x = inRect.x + xOfs + ICON_TRIAN_WIDTH/2 + 1;
points[1].y = inRect.y + inRect.height - 2 - ICON_TRIAN_HEIGHT;
points[2].x = inRect.x + xOfs + ICON_TRIAN_WIDTH+1;
points[2].y = inRect.y + inRect.height - 1;
dc.DrawPolygon( 3, points );
// higlight upper-right edge of triangle
dc.SetPen( mpLayout->mLightPen );
dc.DrawLine( points[2].x, points[2].y,
points[0].x, points[0].y );
dc.SetBrush( wxNullBrush );
}
void cbRowDragPlugin::DrawTrianDown( wxRect& inRect, wxDC& dc )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -