1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: cbRowDragPlugin implementation.
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleksandras Gluchovas
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
23 #include "wx/fl/rowdragpl.h"
25 #define MINIMAL_ROW_DRAG_OFS 5
27 // parameters for row-hints of NC-look
29 #define TRIANGLE_OFFSET 2
30 #define TRIANGLE_TO_PAT_GAP 2
32 #define COLLAPSED_ICON_WIDTH 45
33 #define COLLAPSED_ICON_HEIGHT 9
34 #define ROW_DRAG_HINT_WIDTH 10
35 #define ICON_TRIAN_WIDTH 6
36 #define ICON_TRIAN_HEIGHT 3
38 /***** Implementation for class cbHiddenBarInfo *****/
40 IMPLEMENT_DYNAMIC_CLASS( cbHiddenBarInfo
, wxObject
)
42 /***** Implementation for class cbRowDragPlugin *****/
44 IMPLEMENT_DYNAMIC_CLASS( cbRowDragPlugin
, cbPluginBase
)
46 BEGIN_EVENT_TABLE( cbRowDragPlugin
, cbPluginBase
)
48 EVT_PL_LEFT_DOWN ( cbRowDragPlugin::OnLButtonDown
)
49 EVT_PL_LEFT_UP ( cbRowDragPlugin::OnLButtonUp
)
50 EVT_PL_MOTION ( cbRowDragPlugin::OnMouseMove
)
52 EVT_PL_DRAW_PANE_DECOR ( cbRowDragPlugin::OnDrawPaneBackground
)
56 // FIXME:: how to eliminated these cut and pasted constructors?
58 cbRowDragPlugin::cbRowDragPlugin(void)
60 : mHightColor ( 192, 192, 255 ),
61 mLowColor ( 192, 192, 192 ),
62 mTrianInnerColor ( 0,0,255 ),
63 mTrianInnerPen ( mTrianInnerColor
, 1, wxSOLID
),
65 mDragStarted ( false ),
66 mDecisionMode ( false ),
68 mCaptureIsOn ( false ),
70 mSvBottomMargin ( -1 ),
72 mSvRightMargin ( -1 ),
76 mpCombinedImage ( NULL
),
78 mpRowInFocus ( NULL
),
79 mCollapsedIconInFocus( -1 ),
85 cbRowDragPlugin::cbRowDragPlugin( wxFrameLayout
* pLayout
, int paneMask
)
87 : cbPluginBase( pLayout
, paneMask
),
89 mHightColor ( 192, 192, 255 ),
90 mLowColor ( 192, 192, 192 ),
91 mTrianInnerColor ( 0,0,255 ),
92 mTrianInnerPen ( mTrianInnerColor
, 1, wxSOLID
),
94 mDragStarted ( false ),
95 mDecisionMode ( false ),
97 mCaptureIsOn ( false ),
99 mSvBottomMargin ( -1 ),
100 mSvLeftMargin ( -1 ),
101 mSvRightMargin ( -1 ),
103 mpPaneImage ( NULL
),
105 mpCombinedImage ( NULL
),
107 mpRowInFocus ( NULL
),
108 mCollapsedIconInFocus( -1 ),
114 cbRowDragPlugin::~cbRowDragPlugin()
118 // handlers for plugin events
119 void cbRowDragPlugin::OnMouseMove( cbMotionEvent
& event
)
122 wxPoint pos
= event
.mPos
;
123 mpPane
= event
.mpPane
;
125 mpPane
->PaneToFrame( &pos
.x
, &pos
.y
);
129 if ( mDecisionMode
&& mpRowInFocus
)
133 if ( mpPane
->IsHorizontal() )
135 ofs
= pos
.y
- mDragOrigin
.y
;
137 ofs
= pos
.x
- mDragOrigin
.x
;
139 // check if the item was dragged sufficeintly
140 // far, enough to consider that user really intends
143 if ( ofs
>= MINIMAL_ROW_DRAG_OFS
||
144 ofs
<= -MINIMAL_ROW_DRAG_OFS
)
147 //.wxPoint pos = event.mPos;
148 //wxPoint drg = mDragOrigin;
149 //int dif = event.mPos.x - mDragOrigin.x;
152 mDecisionMode
= false;
159 // this plugin "eats" all mouse input while item is dragged,
163 cbRowInfo
* pRow
= GetFirstRow();
165 bool focusFound
= false;
169 if ( HitTestRowDragHint( pRow
, pos
) )
171 CheckPrevItemInFocus( pRow
, -1 );
172 SetMouseCapture( true );
177 mCollapsedIconInFocus
= -1;
186 int hrCnt
= GetHRowsCountForPane( event
.mpPane
);
188 for( int i
= 0; i
!= hrCnt
; ++i
)
190 if ( HitTestCollapsedRowIcon( i
, pos
) )
192 CheckPrevItemInFocus( NULL
, i
);
193 SetMouseCapture( true );
197 mCollapsedIconInFocus
= i
;
204 if ( !focusFound
&& ItemIsInFocus() )
206 // kill focus from item previously been in focus
207 UnhighlightItemInFocus();
210 mCollapsedIconInFocus
= -1;
211 SetMouseCapture( false );
214 if ( !ItemIsInFocus() )
216 // delegate it to other plugins
221 // otherwise mouse pointer moves, when dragging is started
223 if ( mpPane
->IsHorizontal() )
225 // row is dragged up or down;
226 ShowDraggedRow( pos
.y
- mDragOrigin
.y
);
230 // row is dragged left or right
231 ShowDraggedRow( pos
.x
- mDragOrigin
.x
);
234 // this plugin "eats" all mouse input while item is dragged,
238 void cbRowDragPlugin::OnLButtonDown( cbLeftDownEvent
& event
)
240 mpPane
= event
.mpPane
;
243 wxASSERT( !mDragStarted
&& !mDecisionMode
);
245 if ( ItemIsInFocus() )
247 mDecisionMode
= true;
249 wxPoint pos
= event
.mPos
;
250 mpPane
->PaneToFrame( &pos
.x
, &pos
.y
);
254 SetMouseCapture( true );
257 // propagate event to other plugins
261 void cbRowDragPlugin::OnLButtonUp ( cbLeftUpEvent
& event
)
263 if ( !mDragStarted
&& !mDecisionMode
)
269 mpPane
= event
.mpPane
;
273 cbDockPane
* pPane
= mpPane
;
275 SetMouseCapture( false );
277 mDecisionMode
= false;
278 mDragStarted
= false;
280 wxPoint frmPos
= event
.mPos
;
281 pPane
->PaneToFrame( &frmPos
.x
, &frmPos
.y
);
285 CollapseRow( mpRowInFocus
);
290 ExpandRow( mCollapsedIconInFocus
);
291 mCollapsedIconInFocus
= -1;
297 pPane
->FrameToPane( &frmPos
.x
, &frmPos
.y
);
299 // give it another try after relayouting bars
301 cbMotionEvent
moveEvt( frmPos
, pPane
);
302 this->OnMouseMove( moveEvt
);
304 // this plugin has "eaten" the mouse-up event
310 // otherwise, the dragged row was dropped, determine
311 // where to insert it
313 // restore initial pane appearence
315 FinishOnScreenDraw();
317 cbRowInfo
* pRow
= GetFirstRow();
319 mpLayout
->GetUpdatesManager().OnStartChanges();
321 pRow
->mUMgrData
.SetDirty(true);
323 cbBarInfo
* pBar
= mpRowInFocus
->mBars
[0];
327 pBar
->mUMgrData
.SetDirty(true);
329 if ( pBar
->mpBarWnd
)
331 // do complete refresh
332 pBar
->mpBarWnd
->Show(false);
333 pBar
->mpBarWnd
->Show(true);
341 if ( mCurDragOfs
< pRow
->mRowY
)
343 InsertDraggedRowBefore( pRow
);
350 if ( pRow
== NULL
) InsertDraggedRowBefore( NULL
);
354 mpLayout
->RecalcLayout(false);
356 // finish change "transaction"
357 mpLayout
->GetUpdatesManager().OnFinishChanges();
358 mpLayout
->GetUpdatesManager().UpdateNow();
360 // finish drag action
361 SetMouseCapture( false );
362 mDragStarted
= false;
366 void cbRowDragPlugin::OnDrawPaneBackground ( cbDrawPaneDecorEvent
& event
)
368 mpPane
= event
.mpPane
;
370 // FIXME:: this may harm operation of other plugins
372 if ( GetNextHandler() && mpPane
->GetRowList().GetCount() )
374 // first, let other plugins add their decorations now
376 GetNextHandler()->ProcessEvent( event
);
380 wxClientDC
dc( &mpLayout
->GetParentFrame() );
382 dc
.SetClippingRegion( mpPane
->mBoundsInParent
.x
,
383 mpPane
->mBoundsInParent
.y
,
384 mpPane
->mBoundsInParent
.width
,
385 mpPane
->mBoundsInParent
.height
);
387 int cnt
= GetHRowsCountForPane( event
.mpPane
);
391 DrawCollapsedRowsBorder( dc
);
393 if ( mpPane
->GetRowList().GetCount() )
395 DrawRowsDragHintsBorder( dc
);
397 cbRowInfo
* pRow
= GetFirstRow();
401 DrawRowDragHint( pRow
, dc
, false );
405 for( int i
= 0; i
!= cnt
; ++i
)
407 DrawCollapsedRowIcon(i
, dc
, false );
410 int cbRowDragPlugin::GetHRowsCountForPane( cbDockPane
* pPane
)
412 wxNode
* pNode
= mHiddenBars
.GetFirst();
418 cbHiddenBarInfo
* pHBInfo
= (cbHiddenBarInfo
*)pNode
->GetData();
420 if ( pHBInfo
->mAlignment
== pPane
->mAlignment
)
422 maxIconNo
= wxMax( maxIconNo
, pHBInfo
->mIconNo
);
424 pNode
= pNode
->GetNext();
427 return ( maxIconNo
+ 1 );
430 int cbRowDragPlugin::GetCollapsedRowIconHeight()
432 return COLLAPSED_ICON_HEIGHT
;
435 int cbRowDragPlugin::GetRowDragHintWidth()
437 return ROW_DRAG_HINT_WIDTH
;
440 void cbRowDragPlugin::SetPaneMargins()
442 int hiddenRowsCnt
= GetHRowsCountForPane( mpPane
);
444 if ( mSvTopMargin
== -1 )
446 mSvTopMargin
= mpPane
->mTopMargin
;
447 mSvBottomMargin
= mpPane
->mBottomMargin
;
448 mSvLeftMargin
= mpPane
->mLeftMargin
;
449 mSvRightMargin
= mpPane
->mRightMargin
;
452 if ( mpPane
->IsHorizontal() )
454 mpPane
->mTopMargin
= mSvTopMargin
;
455 mpPane
->mBottomMargin
= ( hiddenRowsCnt
== 0 )
457 : mSvBottomMargin
+ GetCollapsedRowIconHeight();
459 mpPane
->mLeftMargin
= mSvLeftMargin
+ GetRowDragHintWidth();
460 mpPane
->mRightMargin
= mSvRightMargin
;
464 mpPane
->mTopMargin
= mSvTopMargin
;
465 mpPane
->mBottomMargin
= mSvBottomMargin
+ GetRowDragHintWidth();
467 mpPane
->mLeftMargin
= mSvLeftMargin
;
468 mpPane
->mRightMargin
= ( hiddenRowsCnt
== 0 ) ?
469 mSvRightMargin
: mSvRightMargin
+ GetCollapsedRowIconHeight();
473 void cbRowDragPlugin::OnInitPlugin()
475 cbDockPane
** panes
= mpLayout
->GetPanesArray();
477 for( int i
= 0; i
!= MAX_PANES
; ++i
)
479 if ( panes
[i
]->MatchesMask( mPaneMask
) )
487 /*** helpers for drag&drop ***/
489 void cbRowDragPlugin::SetMouseCapture( bool captureOn
)
491 if ( mCaptureIsOn
== captureOn
) return;
495 mpLayout
->CaptureEventsForPane( mpPane
);
496 mpLayout
->CaptureEventsForPlugin( this );
500 mpLayout
->ReleaseEventsFromPane( mpPane
);
501 mpLayout
->ReleaseEventsFromPlugin( this );
504 mCaptureIsOn
= captureOn
;
507 void cbRowDragPlugin::UnhighlightItemInFocus()
509 wxClientDC
dc( &mpLayout
->GetParentFrame() );
513 DrawRowDragHint( mpRowInFocus
, dc
, false );
515 if ( mCollapsedIconInFocus
!= - 1 )
517 DrawCollapsedRowIcon( mCollapsedIconInFocus
, dc
, false );
520 void cbRowDragPlugin::ShowDraggedRow( int offset
)
522 // create combined image of pane and dragged
523 // row on it, in the mpCombinedImage bitmap
525 if ( mpPane
->IsHorizontal() )
527 if ( mInitialRowOfs
+ offset
+ mRowImgDim
.y
> mCombRect
.y
+ mCombRect
.height
)
529 offset
= mCombRect
.y
+ mCombRect
.height
- mRowImgDim
.y
- mInitialRowOfs
;
531 if ( mInitialRowOfs
+ offset
< mCombRect
.y
)
533 offset
= mCombRect
.y
- mInitialRowOfs
;
535 int x
, y
= mInitialRowOfs
+ offset
;
536 mpPane
->FrameToPane( &x
, &y
);
541 if ( mInitialRowOfs
+ offset
+ mRowImgDim
.x
> mCombRect
.x
+ mCombRect
.width
)
543 offset
= mCombRect
.x
+ mCombRect
.width
- mRowImgDim
.x
- mInitialRowOfs
;
545 if ( mInitialRowOfs
+ offset
< mCombRect
.x
)
547 offset
= mCombRect
.x
- mInitialRowOfs
;
549 int x
= mInitialRowOfs
+ offset
, y
;
550 mpPane
->FrameToPane( &x
, &y
);
555 rowImgDc
.SelectObject ( *mpRowImage
);
557 wxMemoryDC paneImgDc
;
558 paneImgDc
.SelectObject( *mpPaneImage
);
560 wxMemoryDC combImgDc
;
561 combImgDc
.SelectObject( *mpCombinedImage
);
563 combImgDc
.Blit( 0,0, mCombRect
.width
, mCombRect
.height
,
564 &paneImgDc
, 0,0, wxCOPY
);
566 if ( mpPane
->IsHorizontal() )
568 combImgDc
.Blit( 0, mInitialRowOfs
+ offset
- mCombRect
.y
,
569 mCombRect
.width
, mRowImgDim
.y
,
570 &rowImgDc
, 0,0, wxCOPY
);
574 combImgDc
.Blit( mInitialRowOfs
+ offset
- mCombRect
.x
,
576 mRowImgDim
.x
, mCombRect
.height
,
577 &rowImgDc
, 0,0, wxCOPY
);
580 int scrX
= mCombRect
.x
,
583 mpLayout
->GetParentFrame().ClientToScreen( &scrX
, &scrY
);
585 mpScrDc
->Blit( scrX
, scrY
, mCombRect
.width
, mCombRect
.height
,
586 &combImgDc
, 0,0, wxCOPY
);
588 rowImgDc
.SelectObject( wxNullBitmap
);
589 paneImgDc
.SelectObject( wxNullBitmap
);
590 combImgDc
.SelectObject( wxNullBitmap
);
593 wxBitmap
* cbRowDragPlugin::CaptureDCArea( wxDC
& dc
, wxRect
& area
)
595 wxBitmap
* pBmp
= new wxBitmap( int(area
.width
), int(area
.height
) );
598 mdc
.SelectObject( *pBmp
);
600 mdc
.Blit( 0,0, area
.width
, area
.height
, &dc
, area
.x
, area
.y
, wxCOPY
);
601 mdc
.SelectObject( wxNullBitmap
);
606 void cbRowDragPlugin::PrepareForRowDrag()
608 wxRect rowBounds
= mpRowInFocus
->mBoundsInParent
;
610 if ( mpPane
->IsHorizontal() )
612 mCombRect
= mpPane
->mBoundsInParent
;
614 mCombRect
.x
+= mpPane
->mLeftMargin
- ROW_DRAG_HINT_WIDTH
- 1;
615 mCombRect
.y
+= mpPane
->mTopMargin
;
617 mCombRect
.width
-= mpPane
->mLeftMargin
+ mpPane
->mRightMargin
- ROW_DRAG_HINT_WIDTH
- 1 - 1;
618 mCombRect
.height
-= mpPane
->mTopMargin
+ mpPane
->mBottomMargin
;
620 mCombRect
.height
+= 2*rowBounds
.height
;
621 mCombRect
.y
-= rowBounds
.height
;
622 mInitialRowOfs
= rowBounds
.y
;
625 rowBounds
.height
+= 2;
626 rowBounds
.x
= mCombRect
.x
;
627 rowBounds
.width
= mCombRect
.width
;
629 mRowImgDim
.y
= rowBounds
.height
;
633 mCombRect
= mpPane
->mBoundsInParent
;
635 mCombRect
.y
+= mpPane
->mTopMargin
- 1;
636 mCombRect
.x
+= mpPane
->mLeftMargin
- 1;
638 mCombRect
.height
-= mpPane
->mTopMargin
+ mpPane
->mBottomMargin
- ROW_DRAG_HINT_WIDTH
- 1 - 1;
639 mCombRect
.width
-= mpPane
->mLeftMargin
+ mpPane
->mRightMargin
;
641 mCombRect
.width
+= 2*rowBounds
.width
;
642 mCombRect
.x
-= rowBounds
.width
;
643 mInitialRowOfs
= rowBounds
.x
;
646 rowBounds
.width
+= 2;
647 rowBounds
.y
= mCombRect
.y
;
648 rowBounds
.height
= mCombRect
.height
;
650 mRowImgDim
.x
= rowBounds
.width
;
652 // output cobination results onto frame's client area
653 wxScreenDC::StartDrawingOnTop(&mpLayout
->GetParentFrame());
654 mpScrDc
= new wxScreenDC();
656 int x
= mCombRect
.x
, y
= mCombRect
.y
;
657 mpLayout
->GetParentFrame().ClientToScreen( &x
, &y
);
659 wxRect scrRect
= mCombRect
;
663 mpPaneImage
= CaptureDCArea( *mpScrDc
, scrRect
);
666 mdc
.SelectObject( *mpPaneImage
);
667 mdc
.SetDeviceOrigin( -mCombRect
.x
, -mCombRect
.y
);
669 DrawRectShade( rowBounds
, mdc
, -1, mpLayout
->mGrayPen
, mpLayout
->mDarkPen
);
670 DrawRectShade( rowBounds
, mdc
, 0, mpLayout
->mLightPen
, mpLayout
->mBlackPen
);
672 mpRowImage
= CaptureDCArea( mdc
, rowBounds
);
674 // draw dark empty-row placeholder
675 DrawEmptyRow( mdc
, rowBounds
);
677 //DrawRectShade( rowBounds, mdc, 0, mpLayout->mGrayPen, mpLayout->mDarkPen );
678 DrawRectShade( rowBounds
, mdc
, -1, mpLayout
->mGrayPen
, mpLayout
->mGrayPen
);
680 mdc
.SelectObject( wxNullBitmap
);
682 mpCombinedImage
= new wxBitmap( int(mCombRect
.width
), int(mCombRect
.height
) );
684 // show it for the first time
688 void cbRowDragPlugin::DrawEmptyRow( wxDC
& dc
, wxRect
& rowBounds
)
690 wxBrush
bkBrush( mpLayout
->mDarkPen
.GetColour(), wxSOLID
);
692 // paint the "dark" empty-row placeholder
694 dc
.SetBrush( bkBrush
);
695 dc
.SetPen ( mpLayout
->mNullPen
);
697 dc
.DrawRectangle( rowBounds
.x
, rowBounds
.y
,
698 rowBounds
.width
+1, rowBounds
.height
+1 );
700 dc
.SetBrush( wxNullBrush
);
703 void cbRowDragPlugin::ShowPaneImage()
705 int scrX
= 0, scrY
= 0;
707 mpLayout
->GetParentFrame().ClientToScreen( &scrX
, &scrY
);
710 mdc
.SelectObject( *mpPaneImage
);
712 mpScrDc
->Blit( mCombRect
.x
+ scrX
, mCombRect
.y
+ scrY
,
713 mCombRect
.width
, mCombRect
.height
,
716 mdc
.SelectObject( wxNullBitmap
);
719 void cbRowDragPlugin::FinishOnScreenDraw()
721 wxScreenDC::EndDrawingOnTop();
724 delete mpCombinedImage
;
730 mpCombinedImage
= mpPaneImage
= mpRowImage
= NULL
;
733 void cbRowDragPlugin::CollapseRow( cbRowInfo
* pRow
)
735 int iconCnt
= GetHRowsCountForPane( mpPane
);
737 mpLayout
->GetUpdatesManager().OnStartChanges();
739 cbBarInfo
* pBar
= pRow
->mBars
[0];
743 cbRowInfo
* pCur
= pRow
;
744 while( pCur
->mpPrev
) { ++rowNo
; pCur
= pCur
->mpPrev
; }
748 cbHiddenBarInfo
* pHBInfo
= new cbHiddenBarInfo();
750 pHBInfo
->mpBar
= pBar
;
751 pHBInfo
->mRowNo
= rowNo
;
752 pHBInfo
->mIconNo
= iconCnt
;
753 pHBInfo
->mAlignment
= mpPane
->mAlignment
;
755 mHiddenBars
.Append( (wxObject
*) pHBInfo
);
758 if ( pBar
->mpBarWnd
)
760 pBar
->mpBarWnd
->Show( false );
762 pBar
->mState
= wxCBAR_HIDDEN
;
764 cbBarInfo
* pNext
= pBar
->mpNext
;
773 mpPane
->GetRowList().Remove( pRow
);
774 mpPane
->InitLinksForRows();
780 mpLayout
->RecalcLayout(false);
784 mpLayout
->GetUpdatesManager().OnFinishChanges();
785 mpLayout
->GetUpdatesManager().UpdateNow();
788 void cbRowDragPlugin::ExpandRow( int collapsedIconIdx
)
790 mpLayout
->GetUpdatesManager().OnStartChanges();
792 cbRowInfo
* pNewRow
= new cbRowInfo();
794 wxNode
* pNode
= mHiddenBars
.GetFirst();
798 // move bars from internal list to the newly expanded row
802 cbHiddenBarInfo
* pHBInfo
= (cbHiddenBarInfo
*)pNode
->GetData();
804 if ( pHBInfo
->mAlignment
== mpPane
->mAlignment
&&
805 pHBInfo
->mIconNo
== collapsedIconIdx
)
807 rowNo
= pHBInfo
->mRowNo
;
809 if ( pHBInfo
->mpBar
->mState
== wxCBAR_HIDDEN
)
811 pNewRow
->mBars
.Add( pHBInfo
->mpBar
);
813 pHBInfo
->mpBar
->mState
= ( mpPane
->IsHorizontal() )
814 ? wxCBAR_DOCKED_HORIZONTALLY
815 : wxCBAR_DOCKED_VERTICALLY
;
818 // remove bar info from internal list
820 wxNode
* pNext
= pNode
->GetNext();
823 mHiddenBars
.DeleteNode( pNode
);
829 // decrease incon numbers with higher indicies, since this
830 // row is now removed from the hidden-rows list
832 if ( pHBInfo
->mIconNo
> collapsedIconIdx
&&
833 pHBInfo
->mAlignment
== mpPane
->mAlignment
)
837 pNode
= pNode
->GetNext();
841 mpPane
->InitLinksForRow( pNewRow
);
843 // insert row into pane at it's original position
845 if ( pNewRow
->mBars
.GetCount() )
847 cbRowInfo
* beforeRowNode
= mpPane
->GetRow( rowNo
);
849 mpPane
->InsertRow( pNewRow
, beforeRowNode
);
856 mpLayout
->RecalcLayout(false);
858 mCollapsedIconInFocus
= -1;
860 mpLayout
->GetUpdatesManager().OnFinishChanges();
861 mpLayout
->GetUpdatesManager().UpdateNow();
865 wxNode* pRowNode = mHiddenRows.Nth( collapsedIconIdx );
867 mpLayout->GetUpdatesManager().OnStartChanges();
869 // insert at the end of rows list
870 mpPane->InsertRow( pRowNode, NULL );
872 int success = mHiddenRows.DeleteNode( pRowNode );
878 mpLayout->RecalcLayout(false);
880 mCollapsedIconInFocus = -1;
882 mpLayout->GetUpdatesManager().OnFinishChanges();
883 mpLayout->GetUpdatesManager().UpdateNow();
887 void cbRowDragPlugin::InsertDraggedRowBefore( cbRowInfo
* pBeforeRow
)
889 if ( mpRowInFocus
!= pBeforeRow
&&
890 mpRowInFocus
->mpNext
!= pBeforeRow
893 mpPane
->GetRowList().Remove( mpRowInFocus
);
895 mpPane
->InsertRow( mpRowInFocus
, pBeforeRow
);
899 // otherwise, nothing has happned (row positions do not change)
901 //wxClientDC dc( &mpLayout->GetParentFrame() );
903 //mpPane->PaintRow( mpRowInFocus, dc );
904 //DrawRowDragHint( mpRowInFocus, dc, false );
908 bool cbRowDragPlugin::ItemIsInFocus()
910 return ( mpRowInFocus
|| mCollapsedIconInFocus
!= - 1 );
913 void cbRowDragPlugin::CheckPrevItemInFocus( cbRowInfo
* pRow
, int iconIdx
)
915 wxClientDC
dc( &mpLayout
->GetParentFrame() );
917 if ( pRow
!= NULL
&& mpRowInFocus
== pRow
) return;
918 if ( iconIdx
!= -1 && mCollapsedIconInFocus
== iconIdx
) return;
920 UnhighlightItemInFocus();
922 if ( iconIdx
!= - 1 )
924 DrawCollapsedRowIcon( iconIdx
, dc
, true );
929 DrawRowDragHint( pRow
, dc
, true );
932 cbRowInfo
* cbRowDragPlugin::GetFirstRow()
934 return ( mpPane
->GetRowList().GetCount() )
935 ? mpPane
->GetRowList()[0]
939 /*** "hard-coded" metafile for NN-look ***/
941 void cbRowDragPlugin::DrawTrianUp( wxRect
& inRect
, wxDC
& dc
)
943 int xOfs
= (inRect
.width
- ICON_TRIAN_WIDTH
)/2;
945 wxBrush
br( mTrianInnerColor
, wxSOLID
);
948 dc
.SetPen( mpLayout
->mBlackPen
);
951 points
[0].x
= inRect
.x
+ xOfs
;
952 points
[0].y
= inRect
.y
+ inRect
.height
- 1;
953 points
[1].x
= inRect
.x
+ xOfs
+ ICON_TRIAN_WIDTH
/2 + 1;
954 points
[1].y
= inRect
.y
+ inRect
.height
- 2 - ICON_TRIAN_HEIGHT
;
955 points
[2].x
= inRect
.x
+ xOfs
+ ICON_TRIAN_WIDTH
+1;
956 points
[2].y
= inRect
.y
+ inRect
.height
- 1;
958 dc
.DrawPolygon( 3, points
);
960 // higlight upper-right edge of triangle
961 dc
.SetPen( mpLayout
->mLightPen
);
962 dc
.DrawLine( points
[2].x
, points
[2].y
,
963 points
[0].x
, points
[0].y
);
965 dc
.SetBrush( wxNullBrush
);
968 void cbRowDragPlugin::DrawTrianDown( wxRect
& inRect
, wxDC
& dc
)
970 int xOfs
= (inRect
.width
- ICON_TRIAN_WIDTH
)/2;
972 wxBrush
br( mTrianInnerColor
, wxSOLID
);
975 dc
.SetPen( mpLayout
->mBlackPen
);
978 points
[0].x
= inRect
.x
+ xOfs
;
979 points
[0].y
= inRect
.y
;
980 points
[1].x
= inRect
.x
+ xOfs
+ ICON_TRIAN_WIDTH
;
981 points
[1].y
= inRect
.y
;
982 points
[2].x
= inRect
.x
+ xOfs
+ ICON_TRIAN_WIDTH
/2;
983 points
[2].y
= inRect
.y
+ ICON_TRIAN_HEIGHT
;
985 dc
.DrawPolygon( 3, points
);
987 // higlight upper-right edge of triangle
988 dc
.SetPen( mpLayout
->mLightPen
);
989 dc
.DrawLine( points
[2].x
, points
[2].y
,
990 points
[1].x
, points
[1].y
);
992 dc
.SetBrush( wxNullBrush
);
995 void cbRowDragPlugin::DrawTrianRight( wxRect
& inRect
, wxDC
& dc
)
997 int yOfs
= (inRect
.height
- ICON_TRIAN_WIDTH
)/2;
999 wxBrush
br( mTrianInnerColor
, wxSOLID
);
1002 dc
.SetPen( mpLayout
->mBlackPen
);
1005 points
[0].x
= inRect
.x
;
1006 points
[0].y
= inRect
.y
+ yOfs
+ ICON_TRIAN_WIDTH
;
1007 points
[1].x
= inRect
.x
;
1008 points
[1].y
= inRect
.y
+ yOfs
;
1009 points
[2].x
= inRect
.x
+ ICON_TRIAN_HEIGHT
;
1010 points
[2].y
= inRect
.y
+ yOfs
+ ICON_TRIAN_WIDTH
/2;
1012 dc
.DrawPolygon( 3, points
);
1014 // higlight upper-right edge of triangle
1015 dc
.SetPen( mpLayout
->mLightPen
);
1016 dc
.DrawLine( points
[0].x
, points
[0].y
,
1017 points
[2].x
, points
[2].y
);
1019 dc
.SetBrush( wxNullBrush
);
1022 void cbRowDragPlugin::Draw3DPattern( wxRect
& inRect
, wxDC
& dc
)
1024 for( int y
= inRect
.y
; y
< inRect
.y
+ inRect
.height
; y
+=3 )
1026 for( int x
= inRect
.x
; x
< inRect
.x
+ inRect
.width
; x
+=3 )
1028 dc
.SetPen( mpLayout
->mLightPen
);
1029 dc
.DrawPoint( x
,y
);
1030 dc
.SetPen( mpLayout
->mBlackPen
);
1031 dc
.DrawPoint( x
+1, y
+1 );
1035 void cbRowDragPlugin::DrawRombShades( wxPoint
& p1
, wxPoint
& p2
,
1036 wxPoint
& p3
, wxPoint
& p4
,
1039 dc
.SetPen( mpLayout
->mLightPen
);
1040 dc
.DrawLine( p1
.x
, p1
.y
, p2
.x
, p2
.y
);
1041 dc
.DrawLine( p2
.x
, p2
.y
, p3
.x
, p3
.y
);
1042 dc
.SetPen( mpLayout
->mDarkPen
);
1043 dc
.DrawLine( p3
.x
, p3
.y
, p4
.x
, p4
.y
);
1044 dc
.DrawLine( p4
.x
, p4
.y
, p1
.x
, p1
.y
);
1047 void cbRowDragPlugin::DrawOrtoRomb( wxRect
& inRect
, wxDC
& dc
, const wxBrush
& bkBrush
)
1049 dc
.SetBrush( bkBrush
);
1050 dc
.SetPen( mpLayout
->mBlackPen
);
1054 if ( inRect
.width
> inRect
.height
)
1056 // horizontal orienation
1057 points
[0].x
= inRect
.x
;
1058 points
[0].y
= inRect
.y
+ inRect
.height
;
1059 points
[1].x
= inRect
.x
;
1060 points
[1].y
= inRect
.y
;
1061 points
[2].x
= inRect
.x
+ inRect
.width
;
1062 points
[2].y
= inRect
.y
;
1063 points
[3].x
= inRect
.x
+ inRect
.width
- COLLAPSED_ICON_HEIGHT
;
1064 points
[3].y
= inRect
.y
+ inRect
.height
;
1066 dc
.DrawPolygon( 4, points
);
1068 // squeeze romb's bounds to create an inner-shade shape
1073 --points
[2].x
; --points
[2].x
;
1077 DrawRombShades( points
[0], points
[1], points
[2], points
[3], dc
);
1081 // vertical orientation
1082 points
[0].x
= inRect
.x
+ inRect
.width
;
1083 points
[0].y
= inRect
.y
+ inRect
.height
;
1084 points
[1].x
= inRect
.x
;
1085 points
[1].y
= inRect
.y
+ inRect
.height
;
1086 points
[2].x
= inRect
.x
;
1087 points
[2].y
= inRect
.y
;
1088 points
[3].x
= inRect
.x
+ inRect
.width
;
1089 points
[3].y
= inRect
.y
+ COLLAPSED_ICON_HEIGHT
;
1091 dc
.DrawPolygon( 4, points
);
1093 // squeeze romb's bounds to create an inner-shade shape
1098 ++points
[2].y
; ++points
[2].y
;
1102 DrawRombShades( points
[1], points
[2], points
[3], points
[0], dc
);
1105 dc
.SetBrush( wxNullBrush
);
1108 void cbRowDragPlugin::DrawRomb( wxRect
& inRect
, wxDC
& dc
, const wxBrush
& bkBrush
)
1112 dc
.SetBrush( bkBrush
);
1113 dc
.SetPen( mpLayout
->mBlackPen
);
1115 if ( inRect
.width
> inRect
.height
)
1117 // horizontal orientation
1118 points
[0].x
= inRect
.x
;
1119 points
[0].y
= inRect
.y
+ inRect
.height
;
1120 points
[1].x
= inRect
.x
+ COLLAPSED_ICON_HEIGHT
;
1121 points
[1].y
= inRect
.y
;
1122 points
[2].x
= inRect
.x
+ inRect
.width
;
1123 points
[2].y
= inRect
.y
;
1124 points
[3].x
= inRect
.x
+ inRect
.width
- COLLAPSED_ICON_HEIGHT
;
1125 points
[3].y
= inRect
.y
+ inRect
.height
;
1127 dc
.DrawPolygon( 4, points
);
1129 // squeeze romb's bounds to create an inner-shade shape
1130 ++points
[0].x
;++points
[0].x
;
1133 --points
[2].x
; --points
[2].x
;
1138 DrawRombShades( points
[0], points
[1], points
[2], points
[3], dc
);
1143 // vertical orientation
1144 points
[0].x
= inRect
.x
+ inRect
.width
;
1145 points
[0].y
= inRect
.y
+ inRect
.height
;
1146 points
[1].x
= inRect
.x
;
1147 points
[1].y
= inRect
.y
+ inRect
.height
- COLLAPSED_ICON_HEIGHT
;
1148 points
[2].x
= inRect
.x
;
1149 points
[2].y
= inRect
.y
;
1150 points
[3].x
= inRect
.x
+ inRect
.width
;
1151 points
[3].y
= inRect
.y
+ COLLAPSED_ICON_HEIGHT
;
1153 dc
.DrawPolygon( 4, points
);
1155 // squeeze romb's bounds to create an inner-shade shape
1156 --points
[0].y
;--points
[0].y
;
1159 ++points
[2].y
; ++points
[2].y
;
1163 DrawRombShades( points
[1], points
[2], points
[3], points
[0], dc
);
1166 dc
.SetBrush( wxNullBrush
);
1169 void cbRowDragPlugin::DrawRectShade( wxRect
& inRect
, wxDC
& dc
,
1170 int level
, const wxPen
& upperPen
, const wxPen
& lowerPen
)
1173 dc
.SetPen( upperPen
);
1174 dc
.DrawLine( inRect
.x
- level
,
1176 inRect
.x
+ inRect
.width
- 1 + level
,
1178 dc
.DrawLine( inRect
.x
- level
, inRect
.y
- level
,
1179 inRect
.x
- level
, inRect
.y
+ inRect
.height
- 1 + level
);
1182 dc
.SetPen( lowerPen
);
1183 dc
.DrawLine( inRect
.x
- level
,
1184 inRect
.y
+ inRect
.height
- 1 + level
,
1185 inRect
.x
+ inRect
.width
+ level
,
1186 inRect
.y
+ inRect
.height
- 1 + level
);
1187 dc
.DrawLine( inRect
.x
+ inRect
.width
- 1 + level
,
1189 inRect
.x
+ inRect
.width
- 1 + level
,
1190 inRect
.y
+ inRect
.height
+ level
);
1192 dc
.SetBrush( wxNullBrush
);
1195 void cbRowDragPlugin::Draw3DRect( wxRect
& inRect
, wxDC
& dc
, const wxBrush
& bkBrush
)
1197 dc
.SetPen( mpLayout
->mNullPen
);
1198 dc
.SetBrush( bkBrush
);
1200 dc
.DrawRectangle( inRect
.x
, inRect
.y
,
1201 inRect
.width
, inRect
.height
);
1203 DrawRectShade( inRect
, dc
, 0, mpLayout
->mLightPen
, mpLayout
->mDarkPen
);
1206 int cbRowDragPlugin::GetCollapsedIconsPos()
1208 RowArrayT
& rows
= mpPane
->GetRowList();
1210 if ( rows
.GetCount() == 0 )
1212 if ( mpPane
->IsHorizontal() )
1214 return mpPane
->mBoundsInParent
.y
+ mpPane
->mTopMargin
;
1216 return mpPane
->mBoundsInParent
.x
+ mpPane
->mLeftMargin
;
1219 wxRect
& bounds
= rows
[ rows
.GetCount() - 1 ]->mBoundsInParent
;
1221 if ( mpPane
->IsHorizontal() )
1223 return bounds
.y
+ bounds
.height
+ 1;
1225 return bounds
.x
+ bounds
.width
+ 1;
1229 void cbRowDragPlugin::GetRowHintRect( cbRowInfo
* pRow
, wxRect
& rect
)
1231 wxRect
& bounds
= pRow
->mBoundsInParent
;
1233 if ( mpPane
->IsHorizontal() )
1235 rect
.x
= bounds
.x
- ROW_DRAG_HINT_WIDTH
- 1;
1237 rect
.width
= ROW_DRAG_HINT_WIDTH
;
1238 rect
.height
= bounds
.height
;
1243 rect
.y
= bounds
.y
+ bounds
.height
+ 1;
1244 rect
.width
= bounds
.width
;
1245 rect
.height
= ROW_DRAG_HINT_WIDTH
;
1249 void cbRowDragPlugin::GetCollapsedInconRect( int iconIdx
, wxRect
& rect
)
1251 int upper
= GetCollapsedIconsPos();
1253 int right
= (iconIdx
== 0 )
1254 ? 0 : iconIdx
* (COLLAPSED_ICON_WIDTH
- COLLAPSED_ICON_HEIGHT
);
1256 if ( mpPane
->IsHorizontal() )
1258 rect
.x
= mpPane
->mBoundsInParent
.x
+ mpPane
->mLeftMargin
- ROW_DRAG_HINT_WIDTH
- 1
1262 rect
.width
= COLLAPSED_ICON_WIDTH
;
1263 rect
.height
= COLLAPSED_ICON_HEIGHT
;
1268 rect
.y
= mpPane
->mBoundsInParent
.y
+ mpPane
->mBoundsInParent
.height
1269 - mpPane
->mBottomMargin
+ ROW_DRAG_HINT_WIDTH
+ 1
1270 - right
- COLLAPSED_ICON_WIDTH
;
1272 rect
.height
= COLLAPSED_ICON_WIDTH
;
1273 rect
.width
= COLLAPSED_ICON_HEIGHT
;
1277 /*** overridables ***/
1279 void cbRowDragPlugin::DrawCollapsedRowIcon( int index
, wxDC
& dc
, bool isHighlighted
)
1282 GetCollapsedInconRect( index
, rect
);
1284 wxBrush
hiBrush ( mHightColor
, wxSOLID
);
1285 wxBrush
lowBrush( mLowColor
, wxSOLID
);
1286 wxBrush
& curBrush
= ( isHighlighted
) ? hiBrush
: lowBrush
;
1288 if ( mpPane
->IsHorizontal() )
1292 DrawOrtoRomb( rect
, dc
, curBrush
);
1294 DrawRomb( rect
, dc
, curBrush
);
1296 int triOfs
= (index
== 0) ? TRIANGLE_OFFSET
: TRIANGLE_OFFSET
+ COLLAPSED_ICON_HEIGHT
;
1299 triRect
.x
= triOfs
+ rect
.x
;
1301 triRect
.width
= ICON_TRIAN_HEIGHT
;
1303 triRect
.height
= rect
.height
;
1305 DrawTrianRight( triRect
, dc
);
1308 patRect
.x
= triOfs
+ ICON_TRIAN_HEIGHT
+ TRIANGLE_TO_PAT_GAP
+ rect
.x
;
1309 patRect
.y
= rect
.y
+ PAT_OFFSET
;
1310 patRect
.width
= rect
.width
- (patRect
.x
- rect
.x
) - COLLAPSED_ICON_HEIGHT
- PAT_OFFSET
;
1311 patRect
.height
= rect
.height
- PAT_OFFSET
*2;
1313 Draw3DPattern( patRect
, dc
);
1319 DrawOrtoRomb( rect
, dc
, curBrush
);
1321 DrawRomb( rect
, dc
, curBrush
);
1323 int triOfs
= (index
== 0)
1324 ? TRIANGLE_OFFSET
+ ICON_TRIAN_HEIGHT
1325 : TRIANGLE_OFFSET
+ COLLAPSED_ICON_HEIGHT
+ ICON_TRIAN_HEIGHT
;
1328 triRect
.y
= rect
.y
+ rect
.height
- triOfs
;
1330 triRect
.width
= rect
.width
;
1331 triRect
.height
= ICON_TRIAN_HEIGHT
;
1333 DrawTrianUp( triRect
, dc
);
1336 patRect
.y
= rect
.y
+ COLLAPSED_ICON_HEIGHT
+ PAT_OFFSET
;
1337 patRect
.x
= rect
.x
+ PAT_OFFSET
;
1338 patRect
.width
= rect
.width
- 2*PAT_OFFSET
;
1339 patRect
.height
= rect
.height
- triOfs
- 2*PAT_OFFSET
- COLLAPSED_ICON_HEIGHT
;
1341 Draw3DPattern( patRect
, dc
);
1345 void cbRowDragPlugin::DrawRowDragHint( cbRowInfo
* pRow
, wxDC
& dc
, bool isHighlighted
)
1348 GetRowHintRect( pRow
, rect
);
1350 wxBrush
hiBrush ( mHightColor
, wxSOLID
);
1351 wxBrush
lowBrush( mLowColor
, wxSOLID
);
1352 wxBrush
& curBrush
= ( isHighlighted
) ? hiBrush
: lowBrush
;
1354 Draw3DRect( rect
, dc
, curBrush
);
1356 if ( mpPane
->IsHorizontal() )
1359 triRect
.y
= rect
.y
+ TRIANGLE_OFFSET
;
1361 triRect
.width
= rect
.width
;
1362 triRect
.height
= ICON_TRIAN_HEIGHT
;
1364 DrawTrianDown( triRect
, dc
);
1367 patRect
.x
= rect
.x
+ PAT_OFFSET
;
1368 patRect
.y
= rect
.y
+ TRIANGLE_OFFSET
+ ICON_TRIAN_HEIGHT
+ TRIANGLE_TO_PAT_GAP
;
1369 patRect
.width
= rect
.width
- 2*PAT_OFFSET
;
1370 patRect
.height
= rect
.height
- ( patRect
.y
- rect
.y
) - PAT_OFFSET
;
1371 Draw3DPattern( patRect
, dc
);
1373 dc
.SetPen( mpLayout
->mLightPen
);
1374 dc
.DrawLine( rect
.x
, rect
.y
+ rect
.height
, rect
.x
+ rect
.width
, rect
.y
+ rect
.height
);
1379 triRect
.x
= rect
.x
+ TRIANGLE_OFFSET
;
1381 triRect
.height
= rect
.height
;
1382 triRect
.width
= ICON_TRIAN_HEIGHT
;
1384 DrawTrianRight( triRect
, dc
);
1387 patRect
.y
= rect
.y
+ PAT_OFFSET
;
1388 patRect
.x
= rect
.x
+ TRIANGLE_OFFSET
+ ICON_TRIAN_HEIGHT
+ TRIANGLE_TO_PAT_GAP
;
1389 patRect
.height
= rect
.height
- 2*PAT_OFFSET
;
1390 patRect
.width
= rect
.width
- ( patRect
.x
- rect
.x
) - PAT_OFFSET
;
1391 Draw3DPattern( patRect
, dc
);
1393 dc
.SetPen( mpLayout
->mLightPen
);
1394 dc
.DrawLine( rect
.x
+ rect
.width
, rect
.y
, rect
.x
+ rect
.width
, rect
.y
+ rect
.height
);
1398 void cbRowDragPlugin::DrawRowsDragHintsBorder( wxDC
& WXUNUSED(dc
) )
1400 // FIXME:: what was that?
1403 void cbRowDragPlugin::DrawCollapsedRowsBorder( wxDC
& dc
)
1405 int colRowOfs
= GetCollapsedIconsPos();
1406 wxRect
& bounds
= mpPane
->mBoundsInParent
;
1408 wxBrush
bkBrush( mpLayout
->mGrayPen
.GetColour(), wxSOLID
);
1409 dc
.SetBrush( bkBrush
);
1410 dc
.SetPen( mpLayout
->mDarkPen
);
1412 if ( mpPane
->IsHorizontal() )
1414 dc
.DrawRectangle( bounds
.x
+ mpPane
->mLeftMargin
- ROW_DRAG_HINT_WIDTH
- 1,
1416 bounds
.width
- mpPane
->mLeftMargin
- mpPane
->mRightMargin
+ 2 + ROW_DRAG_HINT_WIDTH
,
1417 COLLAPSED_ICON_HEIGHT
+ 1);
1419 dc
.DrawRectangle( colRowOfs
,
1420 bounds
.y
+ mpPane
->mTopMargin
- 1,
1421 COLLAPSED_ICON_HEIGHT
+ 1,
1422 bounds
.height
- mpPane
->mTopMargin
- mpPane
->mBottomMargin
1423 - ROW_DRAG_HINT_WIDTH
- 2 );
1425 dc
.SetBrush( wxNullBrush
);
1428 static inline bool rect_contains_point( const wxRect
& rect
, int x
, int y
)
1430 return ( x
>= rect
.x
&&
1432 x
< rect
.x
+ rect
.width
&&
1433 y
< rect
.y
+ rect
.height
);
1436 bool cbRowDragPlugin::HitTestCollapsedRowIcon( int iconIdx
, const wxPoint
& pos
)
1439 GetCollapsedInconRect( iconIdx
, bounds
);
1441 return rect_contains_point( bounds
, pos
.x
, pos
.y
);
1444 bool cbRowDragPlugin::HitTestRowDragHint( cbRowInfo
* pRow
, const wxPoint
& pos
)
1447 GetRowHintRect( pRow
, bounds
);
1449 return rect_contains_point( bounds
, pos
.x
, pos
.y
);