1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: cbRowDragPlugin implementation.
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleksandras Gluchovas
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "rowdragpl.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
27 #include "wx/fl/rowdragpl.h"
29 #define MINIMAL_ROW_DRAG_OFS 5
31 // parameters for row-hints of NC-look
33 #define TRIANGLE_OFFSET 2
34 #define TRIANGLE_TO_PAT_GAP 2
36 #define COLLAPSED_ICON_WIDTH 45
37 #define COLLAPSED_ICON_HEIGHT 9
38 #define ROW_DRAG_HINT_WIDTH 10
39 #define ICON_TRIAN_WIDTH 6
40 #define ICON_TRIAN_HEIGHT 3
42 /***** Implementation for class cbHiddenBarInfo *****/
44 IMPLEMENT_DYNAMIC_CLASS( cbHiddenBarInfo
, wxObject
)
46 /***** Implementation for class cbRowDragPlugin *****/
48 IMPLEMENT_DYNAMIC_CLASS( cbRowDragPlugin
, cbPluginBase
)
50 BEGIN_EVENT_TABLE( cbRowDragPlugin
, cbPluginBase
)
52 EVT_PL_LEFT_DOWN ( cbRowDragPlugin::OnLButtonDown
)
53 EVT_PL_LEFT_UP ( cbRowDragPlugin::OnLButtonUp
)
54 EVT_PL_MOTION ( cbRowDragPlugin::OnMouseMove
)
56 EVT_PL_DRAW_PANE_DECOR ( cbRowDragPlugin::OnDrawPaneBackground
)
60 // FIXME:: how to eliminated these cut and pasted constructors?
62 cbRowDragPlugin::cbRowDragPlugin(void)
64 : mHightColor ( 192, 192, 255 ),
65 mLowColor ( 192, 192, 192 ),
66 mTrianInnerColor ( 0,0,255 ),
67 mTrianInnerPen ( mTrianInnerColor
, 1, wxSOLID
),
69 mDragStarted ( FALSE
),
70 mDecisionMode ( FALSE
),
72 mCaptureIsOn ( FALSE
),
74 mSvBottomMargin ( -1 ),
76 mSvRightMargin ( -1 ),
80 mpCombinedImage ( NULL
),
82 mpRowInFocus ( NULL
),
83 mCollapsedIconInFocus( -1 ),
89 cbRowDragPlugin::cbRowDragPlugin( wxFrameLayout
* pLayout
, int paneMask
)
91 : cbPluginBase( pLayout
, paneMask
),
93 mHightColor ( 192, 192, 255 ),
94 mLowColor ( 192, 192, 192 ),
95 mTrianInnerColor ( 0,0,255 ),
96 mTrianInnerPen ( mTrianInnerColor
, 1, wxSOLID
),
98 mDragStarted ( FALSE
),
99 mDecisionMode ( FALSE
),
101 mCaptureIsOn ( FALSE
),
103 mSvBottomMargin ( -1 ),
104 mSvLeftMargin ( -1 ),
105 mSvRightMargin ( -1 ),
107 mpPaneImage ( NULL
),
109 mpCombinedImage ( NULL
),
111 mpRowInFocus ( NULL
),
112 mCollapsedIconInFocus( -1 ),
118 cbRowDragPlugin::~cbRowDragPlugin()
122 // handlers for plugin events
123 void cbRowDragPlugin::OnMouseMove( cbMotionEvent
& event
)
126 wxPoint pos
= event
.mPos
;
127 mpPane
= event
.mpPane
;
129 mpPane
->PaneToFrame( &pos
.x
, &pos
.y
);
133 if ( mDecisionMode
&& mpRowInFocus
)
137 if ( mpPane
->IsHorizontal() )
139 ofs
= pos
.y
- mDragOrigin
.y
;
141 ofs
= pos
.x
- mDragOrigin
.x
;
143 // check if the item was dragged sufficeintly
144 // far, enough to consider that user really intends
147 if ( ofs
>= MINIMAL_ROW_DRAG_OFS
||
148 ofs
<= -MINIMAL_ROW_DRAG_OFS
)
151 //.wxPoint pos = event.mPos;
152 //wxPoint drg = mDragOrigin;
153 //int dif = event.mPos.x - mDragOrigin.x;
156 mDecisionMode
= FALSE
;
163 // this plugin "eats" all mouse input while item is dragged,
167 cbRowInfo
* pRow
= GetFirstRow();
169 bool focusFound
= FALSE
;
173 if ( HitTestRowDragHint( pRow
, pos
) )
175 CheckPrevItemInFocus( pRow
, -1 );
176 SetMouseCapture( TRUE
);
181 mCollapsedIconInFocus
= -1;
190 int hrCnt
= GetHRowsCountForPane( event
.mpPane
);
192 for( int i
= 0; i
!= hrCnt
; ++i
)
194 if ( HitTestCollapsedRowIcon( i
, pos
) )
196 CheckPrevItemInFocus( NULL
, i
);
197 SetMouseCapture( TRUE
);
201 mCollapsedIconInFocus
= i
;
208 if ( !focusFound
&& ItemIsInFocus() )
210 // kill focus from item previously been in focus
211 UnhighlightItemInFocus();
214 mCollapsedIconInFocus
= -1;
215 SetMouseCapture( FALSE
);
218 if ( !ItemIsInFocus() )
220 // delegate it to other plugins
225 // otherwise mouse pointer moves, when dragging is started
227 if ( mpPane
->IsHorizontal() )
229 // row is dragged up or down;
230 ShowDraggedRow( pos
.y
- mDragOrigin
.y
);
234 // row is dragged left or right
235 ShowDraggedRow( pos
.x
- mDragOrigin
.x
);
238 // this plugin "eats" all mouse input while item is dragged,
242 void cbRowDragPlugin::OnLButtonDown( cbLeftDownEvent
& event
)
244 mpPane
= event
.mpPane
;
247 wxASSERT( !mDragStarted
&& !mDecisionMode
);
249 if ( ItemIsInFocus() )
251 mDecisionMode
= TRUE
;
253 wxPoint pos
= event
.mPos
;
254 mpPane
->PaneToFrame( &pos
.x
, &pos
.y
);
258 SetMouseCapture( TRUE
);
261 // propagate event to other plugins
265 void cbRowDragPlugin::OnLButtonUp ( cbLeftUpEvent
& event
)
267 if ( !mDragStarted
&& !mDecisionMode
)
273 mpPane
= event
.mpPane
;
277 cbDockPane
* pPane
= mpPane
;
279 SetMouseCapture( FALSE
);
281 mDecisionMode
= FALSE
;
282 mDragStarted
= FALSE
;
284 wxPoint frmPos
= event
.mPos
;
285 pPane
->PaneToFrame( &frmPos
.x
, &frmPos
.y
);
289 CollapseRow( mpRowInFocus
);
294 ExpandRow( mCollapsedIconInFocus
);
295 mCollapsedIconInFocus
= -1;
301 pPane
->FrameToPane( &frmPos
.x
, &frmPos
.y
);
303 // give it another try after relayouting bars
305 cbMotionEvent
moveEvt( frmPos
, pPane
);
306 this->OnMouseMove( moveEvt
);
308 // this plugin has "eaten" the mouse-up event
314 // otherwise, the dragged row was dropped, determine
315 // where to insert it
317 // restore initial pane appearence
319 FinishOnScreenDraw();
321 cbRowInfo
* pRow
= GetFirstRow();
323 mpLayout
->GetUpdatesManager().OnStartChanges();
325 pRow
->mUMgrData
.SetDirty(TRUE
);
327 cbBarInfo
* pBar
= mpRowInFocus
->mBars
[0];
331 pBar
->mUMgrData
.SetDirty(TRUE
);
333 if ( pBar
->mpBarWnd
)
335 // do complete refresh
336 pBar
->mpBarWnd
->Show(FALSE
);
337 pBar
->mpBarWnd
->Show(TRUE
);
345 if ( mCurDragOfs
< pRow
->mRowY
)
347 InsertDraggedRowBefore( pRow
);
354 if ( pRow
== NULL
) InsertDraggedRowBefore( NULL
);
358 mpLayout
->RecalcLayout(FALSE
);
360 // finish change "transaction"
361 mpLayout
->GetUpdatesManager().OnFinishChanges();
362 mpLayout
->GetUpdatesManager().UpdateNow();
364 // finish drag action
365 SetMouseCapture( FALSE
);
366 mDragStarted
= FALSE
;
370 void cbRowDragPlugin::OnDrawPaneBackground ( cbDrawPaneDecorEvent
& event
)
372 mpPane
= event
.mpPane
;
374 // FIXME:: this may harm operation of other plugins
376 if ( GetNextHandler() && mpPane
->GetRowList().GetCount() )
378 // first, let other plugins add their decorations now
380 GetNextHandler()->ProcessEvent( event
);
384 wxClientDC
dc( &mpLayout
->GetParentFrame() );
386 dc
.SetClippingRegion( mpPane
->mBoundsInParent
.x
,
387 mpPane
->mBoundsInParent
.y
,
388 mpPane
->mBoundsInParent
.width
,
389 mpPane
->mBoundsInParent
.height
);
391 int cnt
= GetHRowsCountForPane( event
.mpPane
);
395 DrawCollapsedRowsBorder( dc
);
397 if ( mpPane
->GetRowList().GetCount() )
399 DrawRowsDragHintsBorder( dc
);
401 cbRowInfo
* pRow
= GetFirstRow();
405 DrawRowDragHint( pRow
, dc
, FALSE
);
409 for( int i
= 0; i
!= cnt
; ++i
)
411 DrawCollapsedRowIcon(i
, dc
, FALSE
);
414 int cbRowDragPlugin::GetHRowsCountForPane( cbDockPane
* pPane
)
416 wxNode
* pNode
= mHiddenBars
.GetFirst();
422 cbHiddenBarInfo
* pHBInfo
= (cbHiddenBarInfo
*)pNode
->GetData();
424 if ( pHBInfo
->mAlignment
== pPane
->mAlignment
)
426 maxIconNo
= wxMax( maxIconNo
, pHBInfo
->mIconNo
);
428 pNode
= pNode
->GetNext();
431 return ( maxIconNo
+ 1 );
434 int cbRowDragPlugin::GetCollapsedRowIconHeight()
436 return COLLAPSED_ICON_HEIGHT
;
439 int cbRowDragPlugin::GetRowDragHintWidth()
441 return ROW_DRAG_HINT_WIDTH
;
444 void cbRowDragPlugin::SetPaneMargins()
446 int hiddenRowsCnt
= GetHRowsCountForPane( mpPane
);
448 if ( mSvTopMargin
== -1 )
450 mSvTopMargin
= mpPane
->mTopMargin
;
451 mSvBottomMargin
= mpPane
->mBottomMargin
;
452 mSvLeftMargin
= mpPane
->mLeftMargin
;
453 mSvRightMargin
= mpPane
->mRightMargin
;
456 if ( mpPane
->IsHorizontal() )
458 mpPane
->mTopMargin
= mSvTopMargin
;
459 mpPane
->mBottomMargin
= ( hiddenRowsCnt
== 0 )
461 : mSvBottomMargin
+ GetCollapsedRowIconHeight();
463 mpPane
->mLeftMargin
= mSvLeftMargin
+ GetRowDragHintWidth();
464 mpPane
->mRightMargin
= mSvRightMargin
;
468 mpPane
->mTopMargin
= mSvTopMargin
;
469 mpPane
->mBottomMargin
= mSvBottomMargin
+ GetRowDragHintWidth();
471 mpPane
->mLeftMargin
= mSvLeftMargin
;
472 mpPane
->mRightMargin
= ( hiddenRowsCnt
== 0 ) ?
473 mSvRightMargin
: mSvRightMargin
+ GetCollapsedRowIconHeight();
477 void cbRowDragPlugin::OnInitPlugin()
479 cbDockPane
** panes
= mpLayout
->GetPanesArray();
481 for( int i
= 0; i
!= MAX_PANES
; ++i
)
483 if ( panes
[i
]->MatchesMask( mPaneMask
) )
491 /*** helpers for drag&drop ***/
493 void cbRowDragPlugin::SetMouseCapture( bool captureOn
)
495 if ( mCaptureIsOn
== captureOn
) return;
499 mpLayout
->CaptureEventsForPane( mpPane
);
500 mpLayout
->CaptureEventsForPlugin( this );
504 mpLayout
->ReleaseEventsFromPane( mpPane
);
505 mpLayout
->ReleaseEventsFromPlugin( this );
508 mCaptureIsOn
= captureOn
;
511 void cbRowDragPlugin::UnhighlightItemInFocus()
513 wxClientDC
dc( &mpLayout
->GetParentFrame() );
517 DrawRowDragHint( mpRowInFocus
, dc
, FALSE
);
519 if ( mCollapsedIconInFocus
!= - 1 )
521 DrawCollapsedRowIcon( mCollapsedIconInFocus
, dc
, FALSE
);
524 void cbRowDragPlugin::ShowDraggedRow( int offset
)
526 // create combined image of pane and dragged
527 // row on it, in the mpCombinedImage bitmap
529 if ( mpPane
->IsHorizontal() )
531 if ( mInitialRowOfs
+ offset
+ mRowImgDim
.y
> mCombRect
.y
+ mCombRect
.height
)
533 offset
= mCombRect
.y
+ mCombRect
.height
- mRowImgDim
.y
- mInitialRowOfs
;
535 if ( mInitialRowOfs
+ offset
< mCombRect
.y
)
537 offset
= mCombRect
.y
- mInitialRowOfs
;
539 int x
, y
= mInitialRowOfs
+ offset
;
540 mpPane
->FrameToPane( &x
, &y
);
545 if ( mInitialRowOfs
+ offset
+ mRowImgDim
.x
> mCombRect
.x
+ mCombRect
.width
)
547 offset
= mCombRect
.x
+ mCombRect
.width
- mRowImgDim
.x
- mInitialRowOfs
;
549 if ( mInitialRowOfs
+ offset
< mCombRect
.x
)
551 offset
= mCombRect
.x
- mInitialRowOfs
;
553 int x
= mInitialRowOfs
+ offset
, y
;
554 mpPane
->FrameToPane( &x
, &y
);
559 rowImgDc
.SelectObject ( *mpRowImage
);
561 wxMemoryDC paneImgDc
;
562 paneImgDc
.SelectObject( *mpPaneImage
);
564 wxMemoryDC combImgDc
;
565 combImgDc
.SelectObject( *mpCombinedImage
);
567 combImgDc
.Blit( 0,0, mCombRect
.width
, mCombRect
.height
,
568 &paneImgDc
, 0,0, wxCOPY
);
570 if ( mpPane
->IsHorizontal() )
572 combImgDc
.Blit( 0, mInitialRowOfs
+ offset
- mCombRect
.y
,
573 mCombRect
.width
, mRowImgDim
.y
,
574 &rowImgDc
, 0,0, wxCOPY
);
578 combImgDc
.Blit( mInitialRowOfs
+ offset
- mCombRect
.x
,
580 mRowImgDim
.x
, mCombRect
.height
,
581 &rowImgDc
, 0,0, wxCOPY
);
584 int scrX
= mCombRect
.x
,
587 mpLayout
->GetParentFrame().ClientToScreen( &scrX
, &scrY
);
589 mpScrDc
->Blit( scrX
, scrY
, mCombRect
.width
, mCombRect
.height
,
590 &combImgDc
, 0,0, wxCOPY
);
592 rowImgDc
.SelectObject( wxNullBitmap
);
593 paneImgDc
.SelectObject( wxNullBitmap
);
594 combImgDc
.SelectObject( wxNullBitmap
);
597 wxBitmap
* cbRowDragPlugin::CaptureDCArea( wxDC
& dc
, wxRect
& area
)
599 wxBitmap
* pBmp
= new wxBitmap( int(area
.width
), int(area
.height
) );
602 mdc
.SelectObject( *pBmp
);
604 mdc
.Blit( 0,0, area
.width
, area
.height
, &dc
, area
.x
, area
.y
, wxCOPY
);
605 mdc
.SelectObject( wxNullBitmap
);
610 void cbRowDragPlugin::PrepareForRowDrag()
612 wxRect rowBounds
= mpRowInFocus
->mBoundsInParent
;
614 if ( mpPane
->IsHorizontal() )
616 mCombRect
= mpPane
->mBoundsInParent
;
618 mCombRect
.x
+= mpPane
->mLeftMargin
- ROW_DRAG_HINT_WIDTH
- 1;
619 mCombRect
.y
+= mpPane
->mTopMargin
;
621 mCombRect
.width
-= mpPane
->mLeftMargin
+ mpPane
->mRightMargin
- ROW_DRAG_HINT_WIDTH
- 1 - 1;
622 mCombRect
.height
-= mpPane
->mTopMargin
+ mpPane
->mBottomMargin
;
624 mCombRect
.height
+= 2*rowBounds
.height
;
625 mCombRect
.y
-= rowBounds
.height
;
626 mInitialRowOfs
= rowBounds
.y
;
629 rowBounds
.height
+= 2;
630 rowBounds
.x
= mCombRect
.x
;
631 rowBounds
.width
= mCombRect
.width
;
633 mRowImgDim
.y
= rowBounds
.height
;
637 mCombRect
= mpPane
->mBoundsInParent
;
639 mCombRect
.y
+= mpPane
->mTopMargin
- 1;
640 mCombRect
.x
+= mpPane
->mLeftMargin
- 1;
642 mCombRect
.height
-= mpPane
->mTopMargin
+ mpPane
->mBottomMargin
- ROW_DRAG_HINT_WIDTH
- 1 - 1;
643 mCombRect
.width
-= mpPane
->mLeftMargin
+ mpPane
->mRightMargin
;
645 mCombRect
.width
+= 2*rowBounds
.width
;
646 mCombRect
.x
-= rowBounds
.width
;
647 mInitialRowOfs
= rowBounds
.x
;
650 rowBounds
.width
+= 2;
651 rowBounds
.y
= mCombRect
.y
;
652 rowBounds
.height
= mCombRect
.height
;
654 mRowImgDim
.x
= rowBounds
.width
;
656 // output cobination results onto frame's client area
657 wxScreenDC::StartDrawingOnTop(&mpLayout
->GetParentFrame());
658 mpScrDc
= new wxScreenDC();
660 int x
= mCombRect
.x
, y
= mCombRect
.y
;
661 mpLayout
->GetParentFrame().ClientToScreen( &x
, &y
);
663 wxRect scrRect
= mCombRect
;
667 mpPaneImage
= CaptureDCArea( *mpScrDc
, scrRect
);
670 mdc
.SelectObject( *mpPaneImage
);
671 mdc
.SetDeviceOrigin( -mCombRect
.x
, -mCombRect
.y
);
673 DrawRectShade( rowBounds
, mdc
, -1, mpLayout
->mGrayPen
, mpLayout
->mDarkPen
);
674 DrawRectShade( rowBounds
, mdc
, 0, mpLayout
->mLightPen
, mpLayout
->mBlackPen
);
676 mpRowImage
= CaptureDCArea( mdc
, rowBounds
);
678 // draw dark empty-row placeholder
679 DrawEmptyRow( mdc
, rowBounds
);
681 //DrawRectShade( rowBounds, mdc, 0, mpLayout->mGrayPen, mpLayout->mDarkPen );
682 DrawRectShade( rowBounds
, mdc
, -1, mpLayout
->mGrayPen
, mpLayout
->mGrayPen
);
684 mdc
.SelectObject( wxNullBitmap
);
686 mpCombinedImage
= new wxBitmap( int(mCombRect
.width
), int(mCombRect
.height
) );
688 // show it for the first time
692 void cbRowDragPlugin::DrawEmptyRow( wxDC
& dc
, wxRect
& rowBounds
)
694 wxBrush
bkBrush( mpLayout
->mDarkPen
.GetColour(), wxSOLID
);
696 // paint the "dark" empty-row placeholder
698 dc
.SetBrush( bkBrush
);
699 dc
.SetPen ( mpLayout
->mNullPen
);
701 dc
.DrawRectangle( rowBounds
.x
, rowBounds
.y
,
702 rowBounds
.width
+1, rowBounds
.height
+1 );
704 dc
.SetBrush( wxNullBrush
);
707 void cbRowDragPlugin::ShowPaneImage()
709 int scrX
= 0, scrY
= 0;
711 mpLayout
->GetParentFrame().ClientToScreen( &scrX
, &scrY
);
714 mdc
.SelectObject( *mpPaneImage
);
716 mpScrDc
->Blit( mCombRect
.x
+ scrX
, mCombRect
.y
+ scrY
,
717 mCombRect
.width
, mCombRect
.height
,
720 mdc
.SelectObject( wxNullBitmap
);
723 void cbRowDragPlugin::FinishOnScreenDraw()
725 wxScreenDC::EndDrawingOnTop();
728 delete mpCombinedImage
;
734 mpCombinedImage
= mpPaneImage
= mpRowImage
= NULL
;
737 void cbRowDragPlugin::CollapseRow( cbRowInfo
* pRow
)
739 int iconCnt
= GetHRowsCountForPane( mpPane
);
741 mpLayout
->GetUpdatesManager().OnStartChanges();
743 cbBarInfo
* pBar
= pRow
->mBars
[0];
747 cbRowInfo
* pCur
= pRow
;
748 while( pCur
->mpPrev
) { ++rowNo
; pCur
= pCur
->mpPrev
; }
752 cbHiddenBarInfo
* pHBInfo
= new cbHiddenBarInfo();
754 pHBInfo
->mpBar
= pBar
;
755 pHBInfo
->mRowNo
= rowNo
;
756 pHBInfo
->mIconNo
= iconCnt
;
757 pHBInfo
->mAlignment
= mpPane
->mAlignment
;
759 mHiddenBars
.Append( (wxObject
*) pHBInfo
);
762 if ( pBar
->mpBarWnd
)
764 pBar
->mpBarWnd
->Show( FALSE
);
766 pBar
->mState
= wxCBAR_HIDDEN
;
768 cbBarInfo
* pNext
= pBar
->mpNext
;
777 mpPane
->GetRowList().Remove( pRow
);
778 mpPane
->InitLinksForRows();
784 mpLayout
->RecalcLayout(FALSE
);
788 mpLayout
->GetUpdatesManager().OnFinishChanges();
789 mpLayout
->GetUpdatesManager().UpdateNow();
792 void cbRowDragPlugin::ExpandRow( int collapsedIconIdx
)
794 mpLayout
->GetUpdatesManager().OnStartChanges();
796 cbRowInfo
* pNewRow
= new cbRowInfo();
798 wxNode
* pNode
= mHiddenBars
.GetFirst();
802 // move bars from internal list to the newly expanded row
806 cbHiddenBarInfo
* pHBInfo
= (cbHiddenBarInfo
*)pNode
->GetData();
808 if ( pHBInfo
->mAlignment
== mpPane
->mAlignment
&&
809 pHBInfo
->mIconNo
== collapsedIconIdx
)
811 rowNo
= pHBInfo
->mRowNo
;
813 if ( pHBInfo
->mpBar
->mState
== wxCBAR_HIDDEN
)
815 pNewRow
->mBars
.Add( pHBInfo
->mpBar
);
817 pHBInfo
->mpBar
->mState
= ( mpPane
->IsHorizontal() )
818 ? wxCBAR_DOCKED_HORIZONTALLY
819 : wxCBAR_DOCKED_VERTICALLY
;
822 // remove bar info from internal list
824 wxNode
* pNext
= pNode
->GetNext();
827 mHiddenBars
.DeleteNode( pNode
);
833 // decrease incon numbers with higher indicies, since this
834 // row is now removed from the hidden-rows list
836 if ( pHBInfo
->mIconNo
> collapsedIconIdx
&&
837 pHBInfo
->mAlignment
== mpPane
->mAlignment
)
841 pNode
= pNode
->GetNext();
845 mpPane
->InitLinksForRow( pNewRow
);
847 // insert row into pane at it's original position
849 if ( pNewRow
->mBars
.GetCount() )
851 cbRowInfo
* beforeRowNode
= mpPane
->GetRow( rowNo
);
853 mpPane
->InsertRow( pNewRow
, beforeRowNode
);
860 mpLayout
->RecalcLayout(FALSE
);
862 mCollapsedIconInFocus
= -1;
864 mpLayout
->GetUpdatesManager().OnFinishChanges();
865 mpLayout
->GetUpdatesManager().UpdateNow();
869 wxNode* pRowNode = mHiddenRows.Nth( collapsedIconIdx );
871 mpLayout->GetUpdatesManager().OnStartChanges();
873 // insert at the end of rows list
874 mpPane->InsertRow( pRowNode, NULL );
876 int success = mHiddenRows.DeleteNode( pRowNode );
882 mpLayout->RecalcLayout(FALSE);
884 mCollapsedIconInFocus = -1;
886 mpLayout->GetUpdatesManager().OnFinishChanges();
887 mpLayout->GetUpdatesManager().UpdateNow();
891 void cbRowDragPlugin::InsertDraggedRowBefore( cbRowInfo
* pBeforeRow
)
893 if ( mpRowInFocus
!= pBeforeRow
&&
894 mpRowInFocus
->mpNext
!= pBeforeRow
897 mpPane
->GetRowList().Remove( mpRowInFocus
);
899 mpPane
->InsertRow( mpRowInFocus
, pBeforeRow
);
903 // otherwise, nothing has happned (row positions do not change)
905 //wxClientDC dc( &mpLayout->GetParentFrame() );
907 //mpPane->PaintRow( mpRowInFocus, dc );
908 //DrawRowDragHint( mpRowInFocus, dc, FALSE );
912 bool cbRowDragPlugin::ItemIsInFocus()
914 return ( mpRowInFocus
|| mCollapsedIconInFocus
!= - 1 );
917 void cbRowDragPlugin::CheckPrevItemInFocus( cbRowInfo
* pRow
, int iconIdx
)
919 wxClientDC
dc( &mpLayout
->GetParentFrame() );
921 if ( pRow
!= NULL
&& mpRowInFocus
== pRow
) return;
922 if ( iconIdx
!= -1 && mCollapsedIconInFocus
== iconIdx
) return;
924 UnhighlightItemInFocus();
926 if ( iconIdx
!= - 1 )
928 DrawCollapsedRowIcon( iconIdx
, dc
, TRUE
);
933 DrawRowDragHint( pRow
, dc
, TRUE
);
936 cbRowInfo
* cbRowDragPlugin::GetFirstRow()
938 return ( mpPane
->GetRowList().GetCount() )
939 ? mpPane
->GetRowList()[0]
943 /*** "hard-coded" metafile for NN-look ***/
945 void cbRowDragPlugin::DrawTrianUp( wxRect
& inRect
, wxDC
& dc
)
947 int xOfs
= (inRect
.width
- ICON_TRIAN_WIDTH
)/2;
949 wxBrush
br( mTrianInnerColor
, wxSOLID
);
952 dc
.SetPen( mpLayout
->mBlackPen
);
955 points
[0].x
= inRect
.x
+ xOfs
;
956 points
[0].y
= inRect
.y
+ inRect
.height
- 1;
957 points
[1].x
= inRect
.x
+ xOfs
+ ICON_TRIAN_WIDTH
/2 + 1;
958 points
[1].y
= inRect
.y
+ inRect
.height
- 2 - ICON_TRIAN_HEIGHT
;
959 points
[2].x
= inRect
.x
+ xOfs
+ ICON_TRIAN_WIDTH
+1;
960 points
[2].y
= inRect
.y
+ inRect
.height
- 1;
962 dc
.DrawPolygon( 3, points
);
964 // higlight upper-right edge of triangle
965 dc
.SetPen( mpLayout
->mLightPen
);
966 dc
.DrawLine( points
[2].x
, points
[2].y
,
967 points
[0].x
, points
[0].y
);
969 dc
.SetBrush( wxNullBrush
);
972 void cbRowDragPlugin::DrawTrianDown( wxRect
& inRect
, wxDC
& dc
)
974 int xOfs
= (inRect
.width
- ICON_TRIAN_WIDTH
)/2;
976 wxBrush
br( mTrianInnerColor
, wxSOLID
);
979 dc
.SetPen( mpLayout
->mBlackPen
);
982 points
[0].x
= inRect
.x
+ xOfs
;
983 points
[0].y
= inRect
.y
;
984 points
[1].x
= inRect
.x
+ xOfs
+ ICON_TRIAN_WIDTH
;
985 points
[1].y
= inRect
.y
;
986 points
[2].x
= inRect
.x
+ xOfs
+ ICON_TRIAN_WIDTH
/2;
987 points
[2].y
= inRect
.y
+ ICON_TRIAN_HEIGHT
;
989 dc
.DrawPolygon( 3, points
);
991 // higlight upper-right edge of triangle
992 dc
.SetPen( mpLayout
->mLightPen
);
993 dc
.DrawLine( points
[2].x
, points
[2].y
,
994 points
[1].x
, points
[1].y
);
996 dc
.SetBrush( wxNullBrush
);
999 void cbRowDragPlugin::DrawTrianRight( wxRect
& inRect
, wxDC
& dc
)
1001 int yOfs
= (inRect
.height
- ICON_TRIAN_WIDTH
)/2;
1003 wxBrush
br( mTrianInnerColor
, wxSOLID
);
1006 dc
.SetPen( mpLayout
->mBlackPen
);
1009 points
[0].x
= inRect
.x
;
1010 points
[0].y
= inRect
.y
+ yOfs
+ ICON_TRIAN_WIDTH
;
1011 points
[1].x
= inRect
.x
;
1012 points
[1].y
= inRect
.y
+ yOfs
;
1013 points
[2].x
= inRect
.x
+ ICON_TRIAN_HEIGHT
;
1014 points
[2].y
= inRect
.y
+ yOfs
+ ICON_TRIAN_WIDTH
/2;
1016 dc
.DrawPolygon( 3, points
);
1018 // higlight upper-right edge of triangle
1019 dc
.SetPen( mpLayout
->mLightPen
);
1020 dc
.DrawLine( points
[0].x
, points
[0].y
,
1021 points
[2].x
, points
[2].y
);
1023 dc
.SetBrush( wxNullBrush
);
1026 void cbRowDragPlugin::Draw3DPattern( wxRect
& inRect
, wxDC
& dc
)
1028 for( int y
= inRect
.y
; y
< inRect
.y
+ inRect
.height
; y
+=3 )
1030 for( int x
= inRect
.x
; x
< inRect
.x
+ inRect
.width
; x
+=3 )
1032 dc
.SetPen( mpLayout
->mLightPen
);
1033 dc
.DrawPoint( x
,y
);
1034 dc
.SetPen( mpLayout
->mBlackPen
);
1035 dc
.DrawPoint( x
+1, y
+1 );
1039 void cbRowDragPlugin::DrawRombShades( wxPoint
& p1
, wxPoint
& p2
,
1040 wxPoint
& p3
, wxPoint
& p4
,
1043 dc
.SetPen( mpLayout
->mLightPen
);
1044 dc
.DrawLine( p1
.x
, p1
.y
, p2
.x
, p2
.y
);
1045 dc
.DrawLine( p2
.x
, p2
.y
, p3
.x
, p3
.y
);
1046 dc
.SetPen( mpLayout
->mDarkPen
);
1047 dc
.DrawLine( p3
.x
, p3
.y
, p4
.x
, p4
.y
);
1048 dc
.DrawLine( p4
.x
, p4
.y
, p1
.x
, p1
.y
);
1051 void cbRowDragPlugin::DrawOrtoRomb( wxRect
& inRect
, wxDC
& dc
, wxBrush
& bkBrush
)
1053 dc
.SetBrush( bkBrush
);
1054 dc
.SetPen( mpLayout
->mBlackPen
);
1058 if ( inRect
.width
> inRect
.height
)
1060 // horizontal orienation
1061 points
[0].x
= inRect
.x
;
1062 points
[0].y
= inRect
.y
+ inRect
.height
;
1063 points
[1].x
= inRect
.x
;
1064 points
[1].y
= inRect
.y
;
1065 points
[2].x
= inRect
.x
+ inRect
.width
;
1066 points
[2].y
= inRect
.y
;
1067 points
[3].x
= inRect
.x
+ inRect
.width
- COLLAPSED_ICON_HEIGHT
;
1068 points
[3].y
= inRect
.y
+ inRect
.height
;
1070 dc
.DrawPolygon( 4, points
);
1072 // squeeze romb's bounds to create an inner-shade shape
1077 --points
[2].x
; --points
[2].x
;
1081 DrawRombShades( points
[0], points
[1], points
[2], points
[3], dc
);
1085 // vertical orientation
1086 points
[0].x
= inRect
.x
+ inRect
.width
;
1087 points
[0].y
= inRect
.y
+ inRect
.height
;
1088 points
[1].x
= inRect
.x
;
1089 points
[1].y
= inRect
.y
+ inRect
.height
;
1090 points
[2].x
= inRect
.x
;
1091 points
[2].y
= inRect
.y
;
1092 points
[3].x
= inRect
.x
+ inRect
.width
;
1093 points
[3].y
= inRect
.y
+ COLLAPSED_ICON_HEIGHT
;
1095 dc
.DrawPolygon( 4, points
);
1097 // squeeze romb's bounds to create an inner-shade shape
1102 ++points
[2].y
; ++points
[2].y
;
1106 DrawRombShades( points
[1], points
[2], points
[3], points
[0], dc
);
1109 dc
.SetBrush( wxNullBrush
);
1112 void cbRowDragPlugin::DrawRomb( wxRect
& inRect
, wxDC
& dc
, wxBrush
& bkBrush
)
1116 dc
.SetBrush( bkBrush
);
1117 dc
.SetPen( mpLayout
->mBlackPen
);
1119 if ( inRect
.width
> inRect
.height
)
1121 // horizontal orientation
1122 points
[0].x
= inRect
.x
;
1123 points
[0].y
= inRect
.y
+ inRect
.height
;
1124 points
[1].x
= inRect
.x
+ COLLAPSED_ICON_HEIGHT
;
1125 points
[1].y
= inRect
.y
;
1126 points
[2].x
= inRect
.x
+ inRect
.width
;
1127 points
[2].y
= inRect
.y
;
1128 points
[3].x
= inRect
.x
+ inRect
.width
- COLLAPSED_ICON_HEIGHT
;
1129 points
[3].y
= inRect
.y
+ inRect
.height
;
1131 dc
.DrawPolygon( 4, points
);
1133 // squeeze romb's bounds to create an inner-shade shape
1134 ++points
[0].x
;++points
[0].x
;
1137 --points
[2].x
; --points
[2].x
;
1142 DrawRombShades( points
[0], points
[1], points
[2], points
[3], dc
);
1147 // vertical orientation
1148 points
[0].x
= inRect
.x
+ inRect
.width
;
1149 points
[0].y
= inRect
.y
+ inRect
.height
;
1150 points
[1].x
= inRect
.x
;
1151 points
[1].y
= inRect
.y
+ inRect
.height
- COLLAPSED_ICON_HEIGHT
;
1152 points
[2].x
= inRect
.x
;
1153 points
[2].y
= inRect
.y
;
1154 points
[3].x
= inRect
.x
+ inRect
.width
;
1155 points
[3].y
= inRect
.y
+ COLLAPSED_ICON_HEIGHT
;
1157 dc
.DrawPolygon( 4, points
);
1159 // squeeze romb's bounds to create an inner-shade shape
1160 --points
[0].y
;--points
[0].y
;
1163 ++points
[2].y
; ++points
[2].y
;
1167 DrawRombShades( points
[1], points
[2], points
[3], points
[0], dc
);
1170 dc
.SetBrush( wxNullBrush
);
1173 void cbRowDragPlugin::DrawRectShade( wxRect
& inRect
, wxDC
& dc
,
1174 int level
, wxPen
& upperPen
, wxPen
& lowerPen
)
1177 dc
.SetPen( upperPen
);
1178 dc
.DrawLine( inRect
.x
- level
,
1180 inRect
.x
+ inRect
.width
- 1 + level
,
1182 dc
.DrawLine( inRect
.x
- level
, inRect
.y
- level
,
1183 inRect
.x
- level
, inRect
.y
+ inRect
.height
- 1 + level
);
1186 dc
.SetPen( lowerPen
);
1187 dc
.DrawLine( inRect
.x
- level
,
1188 inRect
.y
+ inRect
.height
- 1 + level
,
1189 inRect
.x
+ inRect
.width
+ level
,
1190 inRect
.y
+ inRect
.height
- 1 + level
);
1191 dc
.DrawLine( inRect
.x
+ inRect
.width
- 1 + level
,
1193 inRect
.x
+ inRect
.width
- 1 + level
,
1194 inRect
.y
+ inRect
.height
+ level
);
1196 dc
.SetBrush( wxNullBrush
);
1199 void cbRowDragPlugin::Draw3DRect( wxRect
& inRect
, wxDC
& dc
, wxBrush
& bkBrush
)
1201 dc
.SetPen( mpLayout
->mNullPen
);
1202 dc
.SetBrush( bkBrush
);
1204 dc
.DrawRectangle( inRect
.x
, inRect
.y
,
1205 inRect
.width
, inRect
.height
);
1207 DrawRectShade( inRect
, dc
, 0, mpLayout
->mLightPen
, mpLayout
->mDarkPen
);
1210 int cbRowDragPlugin::GetCollapsedIconsPos()
1212 RowArrayT
& rows
= mpPane
->GetRowList();
1214 if ( rows
.GetCount() == 0 )
1216 if ( mpPane
->IsHorizontal() )
1218 return mpPane
->mBoundsInParent
.y
+ mpPane
->mTopMargin
;
1220 return mpPane
->mBoundsInParent
.x
+ mpPane
->mLeftMargin
;
1223 wxRect
& bounds
= rows
[ rows
.GetCount() - 1 ]->mBoundsInParent
;
1225 if ( mpPane
->IsHorizontal() )
1227 return bounds
.y
+ bounds
.height
+ 1;
1229 return bounds
.x
+ bounds
.width
+ 1;
1233 void cbRowDragPlugin::GetRowHintRect( cbRowInfo
* pRow
, wxRect
& rect
)
1235 wxRect
& bounds
= pRow
->mBoundsInParent
;
1237 if ( mpPane
->IsHorizontal() )
1239 rect
.x
= bounds
.x
- ROW_DRAG_HINT_WIDTH
- 1;
1241 rect
.width
= ROW_DRAG_HINT_WIDTH
;
1242 rect
.height
= bounds
.height
;
1247 rect
.y
= bounds
.y
+ bounds
.height
+ 1;
1248 rect
.width
= bounds
.width
;
1249 rect
.height
= ROW_DRAG_HINT_WIDTH
;
1253 void cbRowDragPlugin::GetCollapsedInconRect( int iconIdx
, wxRect
& rect
)
1255 int upper
= GetCollapsedIconsPos();
1257 int right
= (iconIdx
== 0 )
1258 ? 0 : iconIdx
* (COLLAPSED_ICON_WIDTH
- COLLAPSED_ICON_HEIGHT
);
1260 if ( mpPane
->IsHorizontal() )
1262 rect
.x
= mpPane
->mBoundsInParent
.x
+ mpPane
->mLeftMargin
- ROW_DRAG_HINT_WIDTH
- 1
1266 rect
.width
= COLLAPSED_ICON_WIDTH
;
1267 rect
.height
= COLLAPSED_ICON_HEIGHT
;
1272 rect
.y
= mpPane
->mBoundsInParent
.y
+ mpPane
->mBoundsInParent
.height
1273 - mpPane
->mBottomMargin
+ ROW_DRAG_HINT_WIDTH
+ 1
1274 - right
- COLLAPSED_ICON_WIDTH
;
1276 rect
.height
= COLLAPSED_ICON_WIDTH
;
1277 rect
.width
= COLLAPSED_ICON_HEIGHT
;
1281 /*** overridables ***/
1283 void cbRowDragPlugin::DrawCollapsedRowIcon( int index
, wxDC
& dc
, bool isHighlighted
)
1286 GetCollapsedInconRect( index
, rect
);
1288 wxBrush
hiBrush ( mHightColor
, wxSOLID
);
1289 wxBrush
lowBrush( mLowColor
, wxSOLID
);
1290 wxBrush
& curBrush
= ( isHighlighted
) ? hiBrush
: lowBrush
;
1292 if ( mpPane
->IsHorizontal() )
1296 DrawOrtoRomb( rect
, dc
, curBrush
);
1298 DrawRomb( rect
, dc
, curBrush
);
1300 int triOfs
= (index
== 0) ? TRIANGLE_OFFSET
: TRIANGLE_OFFSET
+ COLLAPSED_ICON_HEIGHT
;
1303 triRect
.x
= triOfs
+ rect
.x
;
1305 triRect
.width
= ICON_TRIAN_HEIGHT
;
1307 triRect
.height
= rect
.height
;
1309 DrawTrianRight( triRect
, dc
);
1312 patRect
.x
= triOfs
+ ICON_TRIAN_HEIGHT
+ TRIANGLE_TO_PAT_GAP
+ rect
.x
;
1313 patRect
.y
= rect
.y
+ PAT_OFFSET
;
1314 patRect
.width
= rect
.width
- (patRect
.x
- rect
.x
) - COLLAPSED_ICON_HEIGHT
- PAT_OFFSET
;
1315 patRect
.height
= rect
.height
- PAT_OFFSET
*2;
1317 Draw3DPattern( patRect
, dc
);
1323 DrawOrtoRomb( rect
, dc
, curBrush
);
1325 DrawRomb( rect
, dc
, curBrush
);
1327 int triOfs
= (index
== 0)
1328 ? TRIANGLE_OFFSET
+ ICON_TRIAN_HEIGHT
1329 : TRIANGLE_OFFSET
+ COLLAPSED_ICON_HEIGHT
+ ICON_TRIAN_HEIGHT
;
1332 triRect
.y
= rect
.y
+ rect
.height
- triOfs
;
1334 triRect
.width
= rect
.width
;
1335 triRect
.height
= ICON_TRIAN_HEIGHT
;
1337 DrawTrianUp( triRect
, dc
);
1340 patRect
.y
= rect
.y
+ COLLAPSED_ICON_HEIGHT
+ PAT_OFFSET
;
1341 patRect
.x
= rect
.x
+ PAT_OFFSET
;
1342 patRect
.width
= rect
.width
- 2*PAT_OFFSET
;
1343 patRect
.height
= rect
.height
- triOfs
- 2*PAT_OFFSET
- COLLAPSED_ICON_HEIGHT
;
1345 Draw3DPattern( patRect
, dc
);
1349 void cbRowDragPlugin::DrawRowDragHint( cbRowInfo
* pRow
, wxDC
& dc
, bool isHighlighted
)
1352 GetRowHintRect( pRow
, rect
);
1354 wxBrush
hiBrush ( mHightColor
, wxSOLID
);
1355 wxBrush
lowBrush( mLowColor
, wxSOLID
);
1356 wxBrush
& curBrush
= ( isHighlighted
) ? hiBrush
: lowBrush
;
1358 Draw3DRect( rect
, dc
, curBrush
);
1360 if ( mpPane
->IsHorizontal() )
1363 triRect
.y
= rect
.y
+ TRIANGLE_OFFSET
;
1365 triRect
.width
= rect
.width
;
1366 triRect
.height
= ICON_TRIAN_HEIGHT
;
1368 DrawTrianDown( triRect
, dc
);
1371 patRect
.x
= rect
.x
+ PAT_OFFSET
;
1372 patRect
.y
= rect
.y
+ TRIANGLE_OFFSET
+ ICON_TRIAN_HEIGHT
+ TRIANGLE_TO_PAT_GAP
;
1373 patRect
.width
= rect
.width
- 2*PAT_OFFSET
;
1374 patRect
.height
= rect
.height
- ( patRect
.y
- rect
.y
) - PAT_OFFSET
;
1375 Draw3DPattern( patRect
, dc
);
1377 dc
.SetPen( mpLayout
->mLightPen
);
1378 dc
.DrawLine( rect
.x
, rect
.y
+ rect
.height
, rect
.x
+ rect
.width
, rect
.y
+ rect
.height
);
1383 triRect
.x
= rect
.x
+ TRIANGLE_OFFSET
;
1385 triRect
.height
= rect
.height
;
1386 triRect
.width
= ICON_TRIAN_HEIGHT
;
1388 DrawTrianRight( triRect
, dc
);
1391 patRect
.y
= rect
.y
+ PAT_OFFSET
;
1392 patRect
.x
= rect
.x
+ TRIANGLE_OFFSET
+ ICON_TRIAN_HEIGHT
+ TRIANGLE_TO_PAT_GAP
;
1393 patRect
.height
= rect
.height
- 2*PAT_OFFSET
;
1394 patRect
.width
= rect
.width
- ( patRect
.x
- rect
.x
) - PAT_OFFSET
;
1395 Draw3DPattern( patRect
, dc
);
1397 dc
.SetPen( mpLayout
->mLightPen
);
1398 dc
.DrawLine( rect
.x
+ rect
.width
, rect
.y
, rect
.x
+ rect
.width
, rect
.y
+ rect
.height
);
1402 void cbRowDragPlugin::DrawRowsDragHintsBorder( wxDC
& WXUNUSED(dc
) )
1404 // FIXME:: what was that?
1407 void cbRowDragPlugin::DrawCollapsedRowsBorder( wxDC
& dc
)
1409 int colRowOfs
= GetCollapsedIconsPos();
1410 wxRect
& bounds
= mpPane
->mBoundsInParent
;
1412 wxBrush
bkBrush( mpLayout
->mGrayPen
.GetColour(), wxSOLID
);
1413 dc
.SetBrush( bkBrush
);
1414 dc
.SetPen( mpLayout
->mDarkPen
);
1416 if ( mpPane
->IsHorizontal() )
1418 dc
.DrawRectangle( bounds
.x
+ mpPane
->mLeftMargin
- ROW_DRAG_HINT_WIDTH
- 1,
1420 bounds
.width
- mpPane
->mLeftMargin
- mpPane
->mRightMargin
+ 2 + ROW_DRAG_HINT_WIDTH
,
1421 COLLAPSED_ICON_HEIGHT
+ 1);
1423 dc
.DrawRectangle( colRowOfs
,
1424 bounds
.y
+ mpPane
->mTopMargin
- 1,
1425 COLLAPSED_ICON_HEIGHT
+ 1,
1426 bounds
.height
- mpPane
->mTopMargin
- mpPane
->mBottomMargin
1427 - ROW_DRAG_HINT_WIDTH
- 2 );
1429 dc
.SetBrush( wxNullBrush
);
1432 static inline bool rect_contains_point( const wxRect
& rect
, int x
, int y
)
1434 return ( x
>= rect
.x
&&
1436 x
< rect
.x
+ rect
.width
&&
1437 y
< rect
.y
+ rect
.height
);
1440 bool cbRowDragPlugin::HitTestCollapsedRowIcon( int iconIdx
, const wxPoint
& pos
)
1443 GetCollapsedInconRect( iconIdx
, bounds
);
1445 return rect_contains_point( bounds
, pos
.x
, pos
.y
);
1448 bool cbRowDragPlugin::HitTestRowDragHint( cbRowInfo
* pRow
, const wxPoint
& pos
)
1451 GetRowHintRect( pRow
, bounds
);
1453 return rect_contains_point( bounds
, pos
.x
, pos
.y
);