1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Contrib. demo
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleksandras Gluchovas
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "rowdragpl.h"
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
28 #include "rowdragpl.h"
30 #define MINIMAL_ROW_DRAG_OFS 5
32 // parameters for row-hints of NC-look
34 #define TRIANGLE_OFFSET 2
35 #define TRIANGLE_TO_PAT_GAP 2
37 #define COLLAPSED_ICON_WIDTH 45
38 #define COLLAPSED_ICON_HEIGHT 9
39 #define ROW_DRAG_HINT_WIDTH 10
40 #define ICON_TRIAN_WIDTH 6
41 #define ICON_TRIAN_HEIGHT 3
43 /***** Implementaiton for class cbHiddenBarInfo *****/
45 IMPLEMENT_DYNAMIC_CLASS( cbHiddenBarInfo
, wxObject
)
47 /***** Implementaiton for class cbRowDragPlugin *****/
49 IMPLEMENT_DYNAMIC_CLASS( cbRowDragPlugin
, cbPluginBase
)
51 BEGIN_EVENT_TABLE( cbRowDragPlugin
, cbPluginBase
)
53 EVT_PL_LEFT_DOWN ( cbRowDragPlugin::OnLButtonDown
)
54 EVT_PL_LEFT_UP ( cbRowDragPlugin::OnLButtonUp
)
55 EVT_PL_MOTION ( cbRowDragPlugin::OnMouseMove
)
57 EVT_PL_DRAW_PANE_DECOR ( cbRowDragPlugin::OnDrawPaneBackground
)
61 // FIXME:: how to eliminated these cut&pasted constructors?
63 cbRowDragPlugin::cbRowDragPlugin(void)
65 : mDragStarted ( FALSE
),
66 mDecisionMode ( FALSE
),
70 mpCombinedImage ( NULL
),
72 mpRowInFocus ( NULL
),
73 mCollapsedIconInFocus( -1 ),
75 mCaptureIsOn ( FALSE
),
77 mTrianInnerColor ( 0,0,255 ),
78 mHightColor ( 192, 192, 255 ),
79 mLowColor ( 192, 192, 192 ),
80 mTrianInnerPen ( mTrianInnerColor
, 1, wxSOLID
),
83 mSvBottomMargin ( -1 ),
85 mSvRightMargin ( -1 ),
90 cbRowDragPlugin::cbRowDragPlugin( wxFrameLayout
* pLayout
, int paneMask
)
92 : cbPluginBase( pLayout
, paneMask
),
94 mDragStarted ( FALSE
),
95 mDecisionMode ( FALSE
),
99 mpCombinedImage ( NULL
),
101 mpRowInFocus ( NULL
),
102 mCollapsedIconInFocus( -1 ),
104 mCaptureIsOn ( FALSE
),
106 mTrianInnerColor ( 0,0,255 ),
107 mHightColor ( 192, 192, 255 ),
108 mLowColor ( 192, 192, 192 ),
109 mTrianInnerPen ( mTrianInnerColor
, 1, wxSOLID
),
112 mSvBottomMargin ( -1 ),
113 mSvLeftMargin ( -1 ),
114 mSvRightMargin ( -1 ),
119 cbRowDragPlugin::~cbRowDragPlugin()
123 // handlers for plugin events
124 void cbRowDragPlugin::OnMouseMove( cbMotionEvent
& event
)
127 wxPoint pos
= event
.mPos
;
128 mpPane
= event
.mpPane
;
130 mpPane
->PaneToFrame( &pos
.x
, &pos
.y
);
134 if ( mDecisionMode
&& mpRowInFocus
)
138 if ( mpPane
->IsHorizontal() )
140 ofs
= pos
.y
- mDragOrigin
.y
;
142 ofs
= pos
.x
- mDragOrigin
.x
;
144 // check if the item was dragged sufficeintly
145 // far, enough to consider that user really intends
148 if ( ofs
>= MINIMAL_ROW_DRAG_OFS
||
149 ofs
<= -MINIMAL_ROW_DRAG_OFS
)
152 //.wxPoint pos = event.mPos;
153 //wxPoint drg = mDragOrigin;
154 //int dif = event.mPos.x - mDragOrigin.x;
157 mDecisionMode
= FALSE
;
164 // this plugin "eats" all mouse input while item is dragged,
168 cbRowInfo
* pRow
= GetFirstRow();
170 bool focusFound
= FALSE
;
174 if ( HitTestRowDragHint( pRow
, pos
) )
176 CheckPrevItemInFocus( pRow
, -1 );
177 SetMouseCapture( TRUE
);
182 mCollapsedIconInFocus
= -1;
191 int hrCnt
= GetHRowsCountForPane( event
.mpPane
);
193 for( int i
= 0; i
!= hrCnt
; ++i
)
195 if ( HitTestCollapsedRowIcon( i
, pos
) )
197 CheckPrevItemInFocus( NULL
, i
);
198 SetMouseCapture( TRUE
);
202 mCollapsedIconInFocus
= i
;
209 if ( !focusFound
&& ItemIsInFocus() )
211 // kill focus from item previousely been in focus
212 UnhiglightItemInFocus();
215 mCollapsedIconInFocus
= -1;
216 SetMouseCapture( FALSE
);
219 if ( !ItemIsInFocus() )
221 // delegate it to other plugins
226 // otherwise mouse pointer moves, when dragging is started
228 if ( mpPane
->IsHorizontal() )
231 wxPoint p
= event
.mPos
;
232 wxPoint d
= mDragOrigin
;
233 int dif
= event
.mPos
.x
- mDragOrigin
.x
;
235 // row is dragged up or down;
236 ShowDraggedRow( pos
.y
- mDragOrigin
.y
);
241 wxPoint p
= event
.mPos
;
242 wxPoint d
= mDragOrigin
;
243 int dif
= event
.mPos
.x
- mDragOrigin
.x
;
245 // row is dragged left or right
246 ShowDraggedRow( pos
.x
- mDragOrigin
.x
);
249 // this plugin "eats" all mouse input while item is dragged,
253 void cbRowDragPlugin::OnLButtonDown( cbLeftDownEvent
& event
)
255 mpPane
= event
.mpPane
;
258 wxASSERT( !mDragStarted
&& !mDecisionMode
);
260 if ( ItemIsInFocus() )
262 mDecisionMode
= TRUE
;
264 wxPoint pos
= event
.mPos
;
265 mpPane
->PaneToFrame( &pos
.x
, &pos
.y
);
269 SetMouseCapture( TRUE
);
272 // propagate event to other plugins
276 void cbRowDragPlugin::OnLButtonUp ( cbLeftUpEvent
& event
)
278 if ( !mDragStarted
&& !mDecisionMode
)
284 mpPane
= event
.mpPane
;
288 cbDockPane
* pPane
= mpPane
;
290 SetMouseCapture( FALSE
);
292 mDecisionMode
= FALSE
;
293 mDragStarted
= FALSE
;
295 wxPoint frmPos
= event
.mPos
;
296 pPane
->PaneToFrame( &frmPos
.x
, &frmPos
.y
);
300 CollapseRow( mpRowInFocus
);
305 ExpandRow( mCollapsedIconInFocus
);
306 mCollapsedIconInFocus
= -1;
312 pPane
->FrameToPane( &frmPos
.x
, &frmPos
.y
);
314 // give it another try after relayouting bars
316 cbMotionEvent
moveEvt( frmPos
, pPane
);
317 this->OnMouseMove( moveEvt
);
319 // this plugin has "eaten" the mouse-up event
325 // otherwise, the dragged row was dropped, determine
326 // where to insert it
328 // restore initial pane appearence
330 FinishOnScreenDraw();
332 cbRowInfo
* pRow
= GetFirstRow();
334 mpLayout
->GetUpdatesManager().OnStartChanges();
336 pRow
->mUMgrData
.SetDirty(TRUE
);
338 cbBarInfo
* pBar
= mpRowInFocus
->mBars
[0];
342 pBar
->mUMgrData
.SetDirty(TRUE
);
344 if ( pBar
->mpBarWnd
)
346 // do complete refresh
347 pBar
->mpBarWnd
->Show(FALSE
);
348 pBar
->mpBarWnd
->Show(TRUE
);
356 if ( mCurDragOfs
< pRow
->mRowY
)
358 InsertDraggedRowBefore( pRow
);
365 if ( pRow
== NULL
) InsertDraggedRowBefore( NULL
);
369 mpLayout
->RecalcLayout(FALSE
);
371 // finish change "transaction"
372 mpLayout
->GetUpdatesManager().OnFinishChanges();
373 mpLayout
->GetUpdatesManager().UpdateNow();
375 // finish drag action
376 SetMouseCapture( FALSE
);
377 mDragStarted
= FALSE
;
381 void cbRowDragPlugin::OnDrawPaneBackground ( cbDrawPaneDecorEvent
& event
)
383 mpPane
= event
.mpPane
;
385 // FIXME:: this may harm operation of other plugins
387 if ( GetNextHandler() && mpPane
->GetRowList().GetCount() )
389 // first, let other plugins add their decorations now
391 GetNextHandler()->ProcessEvent( event
);
395 wxClientDC
dc( &mpLayout
->GetParentFrame() );
397 dc
.SetClippingRegion( mpPane
->mBoundsInParent
.x
,
398 mpPane
->mBoundsInParent
.y
,
399 mpPane
->mBoundsInParent
.width
,
400 mpPane
->mBoundsInParent
.height
);
402 int cnt
= GetHRowsCountForPane( event
.mpPane
);
406 DrawCollapsedRowsBorder( dc
);
408 if ( mpPane
->GetRowList().GetCount() )
410 DrawRowsDragHintsBorder( dc
);
412 cbRowInfo
* pRow
= GetFirstRow();
416 DrawRowDragHint( pRow
, dc
, FALSE
);
420 for( int i
= 0; i
!= cnt
; ++i
)
422 DrawCollapsedRowIcon(i
, dc
, FALSE
);
425 int cbRowDragPlugin::GetHRowsCountForPane( cbDockPane
* pPane
)
427 wxNode
* pNode
= mHiddenBars
.First();
433 cbHiddenBarInfo
* pHBInfo
= (cbHiddenBarInfo
*)pNode
->Data();
435 if ( pHBInfo
->mAlignment
== pPane
->mAlignment
)
437 maxIconNo
= wxMax( maxIconNo
, pHBInfo
->mIconNo
);
439 pNode
= pNode
->Next();
442 return ( maxIconNo
+ 1 );
445 int cbRowDragPlugin::GetCollapsedRowIconHeight()
447 return COLLAPSED_ICON_HEIGHT
;
450 int cbRowDragPlugin::GetRowDragHintWidth()
452 return ROW_DRAG_HINT_WIDTH
;
455 void cbRowDragPlugin::SetPaneMargins()
457 int hiddenRowsCnt
= GetHRowsCountForPane( mpPane
);
459 if ( mSvTopMargin
== -1 )
461 mSvTopMargin
= mpPane
->mTopMargin
;
462 mSvBottomMargin
= mpPane
->mBottomMargin
;
463 mSvLeftMargin
= mpPane
->mLeftMargin
;
464 mSvRightMargin
= mpPane
->mRightMargin
;
467 if ( mpPane
->IsHorizontal() )
469 mpPane
->mTopMargin
= mSvTopMargin
;
470 mpPane
->mBottomMargin
= ( hiddenRowsCnt
== 0 )
472 : mSvBottomMargin
+ GetCollapsedRowIconHeight();
474 mpPane
->mLeftMargin
= mSvLeftMargin
+ GetRowDragHintWidth();
475 mpPane
->mRightMargin
= mSvRightMargin
;
479 mpPane
->mTopMargin
= mSvTopMargin
;
480 mpPane
->mBottomMargin
= mSvBottomMargin
+ GetRowDragHintWidth();
482 mpPane
->mLeftMargin
= mSvLeftMargin
;
483 mpPane
->mRightMargin
= ( hiddenRowsCnt
== 0 ) ?
484 mSvRightMargin
: mSvRightMargin
+ GetCollapsedRowIconHeight();
488 void cbRowDragPlugin::OnInitPlugin()
490 cbDockPane
** panes
= mpLayout
->GetPanesArray();
492 for( int i
= 0; i
!= MAX_PANES
; ++i
)
494 if ( panes
[i
]->MatchesMask( mPaneMask
) )
502 /*** helpers for drag&drop ***/
504 void cbRowDragPlugin::SetMouseCapture( bool captureOn
)
506 if ( mCaptureIsOn
== captureOn
) return;
510 mpLayout
->CaptureEventsForPane( mpPane
);
511 mpLayout
->CaptureEventsForPlugin( this );
515 mpLayout
->ReleaseEventsFromPane( mpPane
);
516 mpLayout
->ReleaseEventsFromPlugin( this );
519 mCaptureIsOn
= captureOn
;
522 void cbRowDragPlugin::UnhiglightItemInFocus()
524 wxClientDC
dc( &mpLayout
->GetParentFrame() );
528 DrawRowDragHint( mpRowInFocus
, dc
, FALSE
);
530 if ( mCollapsedIconInFocus
!= - 1 )
532 DrawCollapsedRowIcon( mCollapsedIconInFocus
, dc
, FALSE
);
535 void cbRowDragPlugin::ShowDraggedRow( int offset
)
537 // create combined image of pane and dragged
538 // row on it, in the mpCombinedImage bitmap
540 if ( mpPane
->IsHorizontal() )
542 if ( mInitalRowOfs
+ offset
+ mRowImgDim
.y
> mCombRect
.y
+ mCombRect
.height
)
544 offset
= mCombRect
.y
+ mCombRect
.height
- mRowImgDim
.y
- mInitalRowOfs
;
546 if ( mInitalRowOfs
+ offset
< mCombRect
.y
)
548 offset
= mCombRect
.y
- mInitalRowOfs
;
550 long x
, y
= mInitalRowOfs
+ offset
;
551 mpPane
->FrameToPane( &x
, &y
);
556 if ( mInitalRowOfs
+ offset
+ mRowImgDim
.x
> mCombRect
.x
+ mCombRect
.width
)
558 offset
= mCombRect
.x
+ mCombRect
.width
- mRowImgDim
.x
- mInitalRowOfs
;
560 if ( mInitalRowOfs
+ offset
< mCombRect
.x
)
562 offset
= mCombRect
.x
- mInitalRowOfs
;
564 long x
= mInitalRowOfs
+ offset
, y
;
565 mpPane
->FrameToPane( &x
, &y
);
570 rowImgDc
.SelectObject ( *mpRowImage
);
572 wxMemoryDC paneImgDc
;
573 paneImgDc
.SelectObject( *mpPaneImage
);
575 wxMemoryDC combImgDc
;
576 combImgDc
.SelectObject( *mpCombinedImage
);
578 combImgDc
.Blit( 0,0, mCombRect
.width
, mCombRect
.height
,
579 &paneImgDc
, 0,0, wxCOPY
);
581 if ( mpPane
->IsHorizontal() )
583 combImgDc
.Blit( 0, mInitalRowOfs
+ offset
- mCombRect
.y
,
584 mCombRect
.width
, mRowImgDim
.y
,
585 &rowImgDc
, 0,0, wxCOPY
);
589 combImgDc
.Blit( mInitalRowOfs
+ offset
- mCombRect
.x
,
591 mRowImgDim
.x
, mCombRect
.height
,
592 &rowImgDc
, 0,0, wxCOPY
);
595 int scrX
= mCombRect
.x
,
598 mpLayout
->GetParentFrame().ClientToScreen( &scrX
, &scrY
);
600 mpScrDc
->Blit( scrX
, scrY
, mCombRect
.width
, mCombRect
.height
,
601 &combImgDc
, 0,0, wxCOPY
);
603 rowImgDc
.SelectObject( wxNullBitmap
);
604 paneImgDc
.SelectObject( wxNullBitmap
);
605 combImgDc
.SelectObject( wxNullBitmap
);
608 wxBitmap
* cbRowDragPlugin::CaptureDCArea( wxDC
& dc
, wxRect
& area
)
610 wxBitmap
* pBmp
= new wxBitmap( int(area
.width
), int(area
.height
) );
613 mdc
.SelectObject( *pBmp
);
615 mdc
.Blit( 0,0, area
.width
, area
.height
, &dc
, area
.x
, area
.y
, wxCOPY
);
616 mdc
.SelectObject( wxNullBitmap
);
621 void cbRowDragPlugin::PrepareForRowDrag()
623 wxRect rowBounds
= mpRowInFocus
->mBoundsInParent
;
625 if ( mpPane
->IsHorizontal() )
627 mCombRect
= mpPane
->mBoundsInParent
;
629 mCombRect
.x
+= mpPane
->mLeftMargin
- ROW_DRAG_HINT_WIDTH
- 1;
630 mCombRect
.y
+= mpPane
->mTopMargin
;
632 mCombRect
.width
-= mpPane
->mLeftMargin
+ mpPane
->mRightMargin
- ROW_DRAG_HINT_WIDTH
- 1 - 1;
633 mCombRect
.height
-= mpPane
->mTopMargin
+ mpPane
->mBottomMargin
;
635 mCombRect
.height
+= 2*rowBounds
.height
;
636 mCombRect
.y
-= rowBounds
.height
;
637 mInitalRowOfs
= rowBounds
.y
;
640 rowBounds
.height
+= 2;
641 rowBounds
.x
= mCombRect
.x
;
642 rowBounds
.width
= mCombRect
.width
;
644 mRowImgDim
.y
= rowBounds
.height
;
648 mCombRect
= mpPane
->mBoundsInParent
;
650 mCombRect
.y
+= mpPane
->mTopMargin
- 1;
651 mCombRect
.x
+= mpPane
->mLeftMargin
- 1;
653 mCombRect
.height
-= mpPane
->mTopMargin
+ mpPane
->mBottomMargin
- ROW_DRAG_HINT_WIDTH
- 1 - 1;
654 mCombRect
.width
-= mpPane
->mLeftMargin
+ mpPane
->mRightMargin
;
656 mCombRect
.width
+= 2*rowBounds
.width
;
657 mCombRect
.x
-= rowBounds
.width
;
658 mInitalRowOfs
= rowBounds
.x
;
661 rowBounds
.width
+= 2;
662 rowBounds
.y
= mCombRect
.y
;
663 rowBounds
.height
= mCombRect
.height
;
665 mRowImgDim
.x
= rowBounds
.width
;
667 // output cobination results onto frame's client area
668 wxScreenDC::StartDrawingOnTop(&mpLayout
->GetParentFrame());
669 mpScrDc
= new wxScreenDC();
671 int x
= mCombRect
.x
, y
= mCombRect
.y
;
672 mpLayout
->GetParentFrame().ClientToScreen( &x
, &y
);
674 wxRect scrRect
= mCombRect
;
678 mpPaneImage
= CaptureDCArea( *mpScrDc
, scrRect
);
681 mdc
.SelectObject( *mpPaneImage
);
682 mdc
.SetDeviceOrigin( -mCombRect
.x
, -mCombRect
.y
);
684 DrawRectShade( rowBounds
, mdc
, -1, mpLayout
->mGrayPen
, mpLayout
->mDarkPen
);
685 DrawRectShade( rowBounds
, mdc
, 0, mpLayout
->mLightPen
, mpLayout
->mBlackPen
);
687 mpRowImage
= CaptureDCArea( mdc
, rowBounds
);
689 // draw dark empty-row placeholder
690 DrawEmptyRow( mdc
, rowBounds
);
692 //DrawRectShade( rowBounds, mdc, 0, mpLayout->mGrayPen, mpLayout->mDarkPen );
693 DrawRectShade( rowBounds
, mdc
, -1, mpLayout
->mGrayPen
, mpLayout
->mGrayPen
);
695 mdc
.SelectObject( wxNullBitmap
);
697 mpCombinedImage
= new wxBitmap( int(mCombRect
.width
), int(mCombRect
.height
) );
699 // show it for the first time
703 void cbRowDragPlugin::DrawEmptyRow( wxDC
& dc
, wxRect
& rowBounds
)
705 wxBrush
bkBrush( mpLayout
->mDarkPen
.GetColour(), wxSOLID
);
707 // paint the "dark" empty-row placeholder
709 dc
.SetBrush( bkBrush
);
710 dc
.SetPen ( mpLayout
->mNullPen
);
712 dc
.DrawRectangle( rowBounds
.x
, rowBounds
.y
,
713 rowBounds
.width
+1, rowBounds
.height
+1 );
715 dc
.SetBrush( wxNullBrush
);
718 void cbRowDragPlugin::ShowPaneImage()
720 int scrX
= 0, scrY
= 0;
722 mpLayout
->GetParentFrame().ClientToScreen( &scrX
, &scrY
);
725 mdc
.SelectObject( *mpPaneImage
);
727 mpScrDc
->Blit( mCombRect
.x
+ scrX
, mCombRect
.y
+ scrY
,
728 mCombRect
.width
, mCombRect
.height
,
731 mdc
.SelectObject( wxNullBitmap
);
734 void cbRowDragPlugin::FinishOnScreenDraw()
736 wxScreenDC::EndDrawingOnTop();
739 delete mpCombinedImage
;
745 mpCombinedImage
= mpPaneImage
= mpRowImage
= NULL
;
748 void cbRowDragPlugin::CollapseRow( cbRowInfo
* pRow
)
750 int iconCnt
= GetHRowsCountForPane( mpPane
);
752 mpLayout
->GetUpdatesManager().OnStartChanges();
754 cbBarInfo
* pBar
= pRow
->mBars
[0];
758 cbRowInfo
* pCur
= pRow
;
759 while( pCur
->mpPrev
) { ++rowNo
; pCur
= pCur
->mpPrev
; }
763 cbHiddenBarInfo
* pHBInfo
= new cbHiddenBarInfo();
765 pHBInfo
->mpBar
= pBar
;
766 pHBInfo
->mRowNo
= rowNo
;
767 pHBInfo
->mIconNo
= iconCnt
;
768 pHBInfo
->mAlignment
= mpPane
->mAlignment
;
770 mHiddenBars
.Append( (wxObject
*) pHBInfo
);
773 if ( pBar
->mpBarWnd
)
775 pBar
->mpBarWnd
->Show( FALSE
);
777 pBar
->mState
= wxCBAR_HIDDEN
;
779 cbBarInfo
* pNext
= pBar
->mpNext
;
788 mpPane
->GetRowList().Remove( pRow
);
789 mpPane
->InitLinksForRows();
795 mpLayout
->RecalcLayout(FALSE
);
799 mpLayout
->GetUpdatesManager().OnFinishChanges();
800 mpLayout
->GetUpdatesManager().UpdateNow();
803 void cbRowDragPlugin::ExpandRow( int collapsedIconIdx
)
805 mpLayout
->GetUpdatesManager().OnStartChanges();
807 cbRowInfo
* pNewRow
= new cbRowInfo();
809 wxNode
* pNode
= mHiddenBars
.First();
813 // move bars from internal list to the newly expanded row
817 cbHiddenBarInfo
* pHBInfo
= (cbHiddenBarInfo
*)pNode
->Data();
819 if ( pHBInfo
->mAlignment
== mpPane
->mAlignment
&&
820 pHBInfo
->mIconNo
== collapsedIconIdx
)
822 rowNo
= pHBInfo
->mRowNo
;
824 if ( pHBInfo
->mpBar
->mState
== wxCBAR_HIDDEN
)
826 pNewRow
->mBars
.Add( pHBInfo
->mpBar
);
828 pHBInfo
->mpBar
->mState
= ( mpPane
->IsHorizontal() )
829 ? wxCBAR_DOCKED_HORIZONTALLY
830 : wxCBAR_DOCKED_VERTICALLY
;
833 // remove bar info from internal list
835 wxNode
* pNext
= pNode
->Next();
838 mHiddenBars
.DeleteNode( pNode
);
844 // decrease incon numbers with higher indicies, since this
845 // row is now removed from the hidden-rows list
847 if ( pHBInfo
->mIconNo
> collapsedIconIdx
&&
848 pHBInfo
->mAlignment
== mpPane
->mAlignment
)
852 pNode
= pNode
->Next();
856 mpPane
->InitLinksForRow( pNewRow
);
858 // insert row into pane at it's original position
860 if ( pNewRow
->mBars
.GetCount() )
862 cbRowInfo
* beforeRowNode
= mpPane
->GetRow( rowNo
);
864 mpPane
->InsertRow( pNewRow
, beforeRowNode
);
871 mpLayout
->RecalcLayout(FALSE
);
873 mCollapsedIconInFocus
= -1;
875 mpLayout
->GetUpdatesManager().OnFinishChanges();
876 mpLayout
->GetUpdatesManager().UpdateNow();
880 wxNode* pRowNode = mHiddenRows.Nth( collapsedIconIdx );
882 mpLayout->GetUpdatesManager().OnStartChanges();
884 // insert at the end of rows list
885 mpPane->InsertRow( pRowNode, NULL );
887 int success = mHiddenRows.DeleteNode( pRowNode );
893 mpLayout->RecalcLayout(FALSE);
895 mCollapsedIconInFocus = -1;
897 mpLayout->GetUpdatesManager().OnFinishChanges();
898 mpLayout->GetUpdatesManager().UpdateNow();
902 void cbRowDragPlugin::InsertDraggedRowBefore( cbRowInfo
* pBeforeRow
)
904 if ( mpRowInFocus
!= pBeforeRow
&&
905 mpRowInFocus
->mpNext
!= pBeforeRow
908 mpPane
->GetRowList().Remove( mpRowInFocus
);
910 mpPane
->InsertRow( mpRowInFocus
, pBeforeRow
);
914 // otherwise, nothing has happned (row positions do not change)
916 //wxClientDC dc( &mpLayout->GetParentFrame() );
918 //mpPane->PaintRow( mpRowInFocus, dc );
919 //DrawRowDragHint( mpRowInFocus, dc, FALSE );
923 bool cbRowDragPlugin::ItemIsInFocus()
925 return ( mpRowInFocus
|| mCollapsedIconInFocus
!= - 1 );
928 void cbRowDragPlugin::CheckPrevItemInFocus( cbRowInfo
* pRow
, int iconIdx
)
930 wxClientDC
dc( &mpLayout
->GetParentFrame() );
932 if ( pRow
!= NULL
&& mpRowInFocus
== pRow
) return;
933 if ( iconIdx
!= -1 && mCollapsedIconInFocus
== iconIdx
) return;
935 UnhiglightItemInFocus();
937 if ( iconIdx
!= - 1 )
939 DrawCollapsedRowIcon( iconIdx
, dc
, TRUE
);
944 DrawRowDragHint( pRow
, dc
, TRUE
);
947 cbRowInfo
* cbRowDragPlugin::GetFirstRow()
949 return ( mpPane
->GetRowList().GetCount() )
950 ? mpPane
->GetRowList()[0]
954 /*** "hard-coded" metafile for NN-look ***/
956 void cbRowDragPlugin::DrawTrianUp( wxRect
& inRect
, wxDC
& dc
)
958 int xOfs
= (inRect
.width
- ICON_TRIAN_WIDTH
)/2;
960 wxBrush
br( mTrianInnerColor
, wxSOLID
);
963 dc
.SetPen( mpLayout
->mBlackPen
);
966 points
[0].x
= inRect
.x
+ xOfs
;
967 points
[0].y
= inRect
.y
+ inRect
.height
- 1;
968 points
[1].x
= inRect
.x
+ xOfs
+ ICON_TRIAN_WIDTH
/2 + 1;
969 points
[1].y
= inRect
.y
+ inRect
.height
- 2 - ICON_TRIAN_HEIGHT
;
970 points
[2].x
= inRect
.x
+ xOfs
+ ICON_TRIAN_WIDTH
+1;
971 points
[2].y
= inRect
.y
+ inRect
.height
- 1;
973 dc
.DrawPolygon( 3, points
);
975 // higlight upper-right edge of triangle
976 dc
.SetPen( mpLayout
->mLightPen
);
977 dc
.DrawLine( points
[2].x
, points
[2].y
,
978 points
[0].x
, points
[0].y
);
980 dc
.SetBrush( wxNullBrush
);
983 void cbRowDragPlugin::DrawTrianDown( wxRect
& inRect
, wxDC
& dc
)
985 int xOfs
= (inRect
.width
- ICON_TRIAN_WIDTH
)/2;
987 wxBrush
br( mTrianInnerColor
, wxSOLID
);
990 dc
.SetPen( mpLayout
->mBlackPen
);
993 points
[0].x
= inRect
.x
+ xOfs
;
994 points
[0].y
= inRect
.y
;
995 points
[1].x
= inRect
.x
+ xOfs
+ ICON_TRIAN_WIDTH
;
996 points
[1].y
= inRect
.y
;
997 points
[2].x
= inRect
.x
+ xOfs
+ ICON_TRIAN_WIDTH
/2;
998 points
[2].y
= inRect
.y
+ ICON_TRIAN_HEIGHT
;
1000 dc
.DrawPolygon( 3, points
);
1002 // higlight upper-right edge of triangle
1003 dc
.SetPen( mpLayout
->mLightPen
);
1004 dc
.DrawLine( points
[2].x
, points
[2].y
,
1005 points
[1].x
, points
[1].y
);
1007 dc
.SetBrush( wxNullBrush
);
1010 void cbRowDragPlugin::DrawTrianRight( wxRect
& inRect
, wxDC
& dc
)
1012 int yOfs
= (inRect
.height
- ICON_TRIAN_WIDTH
)/2;
1014 wxBrush
br( mTrianInnerColor
, wxSOLID
);
1017 dc
.SetPen( mpLayout
->mBlackPen
);
1020 points
[0].x
= inRect
.x
;
1021 points
[0].y
= inRect
.y
+ yOfs
+ ICON_TRIAN_WIDTH
;
1022 points
[1].x
= inRect
.x
;
1023 points
[1].y
= inRect
.y
+ yOfs
;
1024 points
[2].x
= inRect
.x
+ ICON_TRIAN_HEIGHT
;
1025 points
[2].y
= inRect
.y
+ yOfs
+ ICON_TRIAN_WIDTH
/2;
1027 dc
.DrawPolygon( 3, points
);
1029 // higlight upper-right edge of triangle
1030 dc
.SetPen( mpLayout
->mLightPen
);
1031 dc
.DrawLine( points
[0].x
, points
[0].y
,
1032 points
[2].x
, points
[2].y
);
1034 dc
.SetBrush( wxNullBrush
);
1037 void cbRowDragPlugin::Draw3DPattern( wxRect
& inRect
, wxDC
& dc
)
1039 for( int y
= inRect
.y
; y
< inRect
.y
+ inRect
.height
; y
+=3 )
1041 for( int x
= inRect
.x
; x
< inRect
.x
+ inRect
.width
; x
+=3 )
1043 dc
.SetPen( mpLayout
->mLightPen
);
1044 dc
.DrawPoint( x
,y
);
1045 dc
.SetPen( mpLayout
->mBlackPen
);
1046 dc
.DrawPoint( x
+1, y
+1 );
1050 void cbRowDragPlugin::DrawRombShades( wxPoint
& p1
, wxPoint
& p2
,
1051 wxPoint
& p3
, wxPoint
& p4
,
1054 dc
.SetPen( mpLayout
->mLightPen
);
1055 dc
.DrawLine( p1
.x
, p1
.y
, p2
.x
, p2
.y
);
1056 dc
.DrawLine( p2
.x
, p2
.y
, p3
.x
, p3
.y
);
1057 dc
.SetPen( mpLayout
->mDarkPen
);
1058 dc
.DrawLine( p3
.x
, p3
.y
, p4
.x
, p4
.y
);
1059 dc
.DrawLine( p4
.x
, p4
.y
, p1
.x
, p1
.y
);
1062 void cbRowDragPlugin::DrawOrtoRomb( wxRect
& inRect
, wxDC
& dc
, wxBrush
& bkBrush
)
1064 dc
.SetBrush( bkBrush
);
1065 dc
.SetPen( mpLayout
->mBlackPen
);
1069 if ( inRect
.width
> inRect
.height
)
1071 // horizontal orienation
1072 points
[0].x
= inRect
.x
;
1073 points
[0].y
= inRect
.y
+ inRect
.height
;
1074 points
[1].x
= inRect
.x
;
1075 points
[1].y
= inRect
.y
;
1076 points
[2].x
= inRect
.x
+ inRect
.width
;
1077 points
[2].y
= inRect
.y
;
1078 points
[3].x
= inRect
.x
+ inRect
.width
- COLLAPSED_ICON_HEIGHT
;
1079 points
[3].y
= inRect
.y
+ inRect
.height
;
1081 dc
.DrawPolygon( 4, points
);
1083 // squeeze romb's bounds to create an inner-shade shape
1088 --points
[2].x
; --points
[2].x
;
1092 DrawRombShades( points
[0], points
[1], points
[2], points
[3], dc
);
1096 // vertical orientation
1097 points
[0].x
= inRect
.x
+ inRect
.width
;
1098 points
[0].y
= inRect
.y
+ inRect
.height
;
1099 points
[1].x
= inRect
.x
;
1100 points
[1].y
= inRect
.y
+ inRect
.height
;
1101 points
[2].x
= inRect
.x
;
1102 points
[2].y
= inRect
.y
;
1103 points
[3].x
= inRect
.x
+ inRect
.width
;
1104 points
[3].y
= inRect
.y
+ COLLAPSED_ICON_HEIGHT
;
1106 dc
.DrawPolygon( 4, points
);
1108 // squeeze romb's bounds to create an inner-shade shape
1113 ++points
[2].y
; ++points
[2].y
;
1117 DrawRombShades( points
[1], points
[2], points
[3], points
[0], dc
);
1120 dc
.SetBrush( wxNullBrush
);
1123 void cbRowDragPlugin::DrawRomb( wxRect
& inRect
, wxDC
& dc
, wxBrush
& bkBrush
)
1127 dc
.SetBrush( bkBrush
);
1128 dc
.SetPen( mpLayout
->mBlackPen
);
1130 if ( inRect
.width
> inRect
.height
)
1132 // horizontal orientation
1133 points
[0].x
= inRect
.x
;
1134 points
[0].y
= inRect
.y
+ inRect
.height
;
1135 points
[1].x
= inRect
.x
+ COLLAPSED_ICON_HEIGHT
;
1136 points
[1].y
= inRect
.y
;
1137 points
[2].x
= inRect
.x
+ inRect
.width
;
1138 points
[2].y
= inRect
.y
;
1139 points
[3].x
= inRect
.x
+ inRect
.width
- COLLAPSED_ICON_HEIGHT
;
1140 points
[3].y
= inRect
.y
+ inRect
.height
;
1142 dc
.DrawPolygon( 4, points
);
1144 // squeeze romb's bounds to create an inner-shade shape
1145 ++points
[0].x
;++points
[0].x
;
1148 --points
[2].x
; --points
[2].x
;
1153 DrawRombShades( points
[0], points
[1], points
[2], points
[3], dc
);
1158 // vertical orientation
1159 points
[0].x
= inRect
.x
+ inRect
.width
;
1160 points
[0].y
= inRect
.y
+ inRect
.height
;
1161 points
[1].x
= inRect
.x
;
1162 points
[1].y
= inRect
.y
+ inRect
.height
- COLLAPSED_ICON_HEIGHT
;
1163 points
[2].x
= inRect
.x
;
1164 points
[2].y
= inRect
.y
;
1165 points
[3].x
= inRect
.x
+ inRect
.width
;
1166 points
[3].y
= inRect
.y
+ COLLAPSED_ICON_HEIGHT
;
1168 dc
.DrawPolygon( 4, points
);
1170 // squeeze romb's bounds to create an inner-shade shape
1171 --points
[0].y
;--points
[0].y
;
1174 ++points
[2].y
; ++points
[2].y
;
1178 DrawRombShades( points
[1], points
[2], points
[3], points
[0], dc
);
1181 dc
.SetBrush( wxNullBrush
);
1184 void cbRowDragPlugin::DrawRectShade( wxRect
& inRect
, wxDC
& dc
,
1185 int level
, wxPen
& upperPen
, wxPen
& lowerPen
)
1188 dc
.SetPen( upperPen
);
1189 dc
.DrawLine( inRect
.x
- level
,
1191 inRect
.x
+ inRect
.width
- 1 + level
,
1193 dc
.DrawLine( inRect
.x
- level
, inRect
.y
- level
,
1194 inRect
.x
- level
, inRect
.y
+ inRect
.height
- 1 + level
);
1197 dc
.SetPen( lowerPen
);
1198 dc
.DrawLine( inRect
.x
- level
,
1199 inRect
.y
+ inRect
.height
- 1 + level
,
1200 inRect
.x
+ inRect
.width
+ level
,
1201 inRect
.y
+ inRect
.height
- 1 + level
);
1202 dc
.DrawLine( inRect
.x
+ inRect
.width
- 1 + level
,
1204 inRect
.x
+ inRect
.width
- 1 + level
,
1205 inRect
.y
+ inRect
.height
+ level
);
1207 dc
.SetBrush( wxNullBrush
);
1210 void cbRowDragPlugin::Draw3DRect( wxRect
& inRect
, wxDC
& dc
, wxBrush
& bkBrush
)
1212 dc
.SetPen( mpLayout
->mNullPen
);
1213 dc
.SetBrush( bkBrush
);
1215 dc
.DrawRectangle( inRect
.x
, inRect
.y
,
1216 inRect
.width
, inRect
.height
);
1218 DrawRectShade( inRect
, dc
, 0, mpLayout
->mLightPen
, mpLayout
->mDarkPen
);
1221 int cbRowDragPlugin::GetCollapsedIconsPos()
1223 RowArrayT
& rows
= mpPane
->GetRowList();
1225 if ( rows
.GetCount() == 0 )
1227 if ( mpPane
->IsHorizontal() )
1229 return mpPane
->mBoundsInParent
.y
+ mpPane
->mTopMargin
;
1231 return mpPane
->mBoundsInParent
.x
+ mpPane
->mLeftMargin
;
1234 wxRect
& bounds
= rows
[ rows
.GetCount() - 1 ]->mBoundsInParent
;
1236 if ( mpPane
->IsHorizontal() )
1238 return bounds
.y
+ bounds
.height
+ 1;
1240 return bounds
.x
+ bounds
.width
+ 1;
1244 void cbRowDragPlugin::GetRowHintRect( cbRowInfo
* pRow
, wxRect
& rect
)
1246 wxRect
& bounds
= pRow
->mBoundsInParent
;
1248 if ( mpPane
->IsHorizontal() )
1250 rect
.x
= bounds
.x
- ROW_DRAG_HINT_WIDTH
- 1;
1252 rect
.width
= ROW_DRAG_HINT_WIDTH
;
1253 rect
.height
= bounds
.height
;
1258 rect
.y
= bounds
.y
+ bounds
.height
+ 1;
1259 rect
.width
= bounds
.width
;
1260 rect
.height
= ROW_DRAG_HINT_WIDTH
;
1264 void cbRowDragPlugin::GetCollapsedInconRect( int iconIdx
, wxRect
& rect
)
1266 int upper
= GetCollapsedIconsPos();
1268 int right
= (iconIdx
== 0 )
1269 ? 0 : iconIdx
* (COLLAPSED_ICON_WIDTH
- COLLAPSED_ICON_HEIGHT
);
1271 if ( mpPane
->IsHorizontal() )
1273 rect
.x
= mpPane
->mBoundsInParent
.x
+ mpPane
->mLeftMargin
- ROW_DRAG_HINT_WIDTH
- 1
1277 rect
.width
= COLLAPSED_ICON_WIDTH
;
1278 rect
.height
= COLLAPSED_ICON_HEIGHT
;
1283 rect
.y
= mpPane
->mBoundsInParent
.y
+ mpPane
->mBoundsInParent
.height
1284 - mpPane
->mBottomMargin
+ ROW_DRAG_HINT_WIDTH
+ 1
1285 - right
- COLLAPSED_ICON_WIDTH
;
1287 rect
.height
= COLLAPSED_ICON_WIDTH
;
1288 rect
.width
= COLLAPSED_ICON_HEIGHT
;
1292 /*** overridables ***/
1294 void cbRowDragPlugin::DrawCollapsedRowIcon( int index
, wxDC
& dc
, bool isHighlighted
)
1297 GetCollapsedInconRect( index
, rect
);
1299 wxBrush
hiBrush ( mHightColor
, wxSOLID
);
1300 wxBrush
lowBrush( mLowColor
, wxSOLID
);
1301 wxBrush
& curBrush
= ( isHighlighted
) ? hiBrush
: lowBrush
;
1303 if ( mpPane
->IsHorizontal() )
1307 DrawOrtoRomb( rect
, dc
, curBrush
);
1309 DrawRomb( rect
, dc
, curBrush
);
1311 int triOfs
= (index
== 0) ? TRIANGLE_OFFSET
: TRIANGLE_OFFSET
+ COLLAPSED_ICON_HEIGHT
;
1314 triRect
.x
= triOfs
+ rect
.x
;
1316 triRect
.width
= ICON_TRIAN_HEIGHT
;
1318 triRect
.height
= rect
.height
;
1320 DrawTrianRight( triRect
, dc
);
1323 patRect
.x
= triOfs
+ ICON_TRIAN_HEIGHT
+ TRIANGLE_TO_PAT_GAP
+ rect
.x
;
1324 patRect
.y
= rect
.y
+ PAT_OFFSET
;
1325 patRect
.width
= rect
.width
- (patRect
.x
- rect
.x
) - COLLAPSED_ICON_HEIGHT
- PAT_OFFSET
;
1326 patRect
.height
= rect
.height
- PAT_OFFSET
*2;
1328 Draw3DPattern( patRect
, dc
);
1334 DrawOrtoRomb( rect
, dc
, curBrush
);
1336 DrawRomb( rect
, dc
, curBrush
);
1338 int triOfs
= (index
== 0)
1339 ? TRIANGLE_OFFSET
+ ICON_TRIAN_HEIGHT
1340 : TRIANGLE_OFFSET
+ COLLAPSED_ICON_HEIGHT
+ ICON_TRIAN_HEIGHT
;
1343 triRect
.y
= rect
.y
+ rect
.height
- triOfs
;
1345 triRect
.width
= rect
.width
;
1346 triRect
.height
= ICON_TRIAN_HEIGHT
;
1348 DrawTrianUp( triRect
, dc
);
1351 patRect
.y
= rect
.y
+ COLLAPSED_ICON_HEIGHT
+ PAT_OFFSET
;
1352 patRect
.x
= rect
.x
+ PAT_OFFSET
;
1353 patRect
.width
= rect
.width
- 2*PAT_OFFSET
;
1354 patRect
.height
= rect
.height
- triOfs
- 2*PAT_OFFSET
- COLLAPSED_ICON_HEIGHT
;
1356 Draw3DPattern( patRect
, dc
);
1360 void cbRowDragPlugin::DrawRowDragHint( cbRowInfo
* pRow
, wxDC
& dc
, bool isHighlighted
)
1363 GetRowHintRect( pRow
, rect
);
1365 wxBrush
hiBrush ( mHightColor
, wxSOLID
);
1366 wxBrush
lowBrush( mLowColor
, wxSOLID
);
1367 wxBrush
& curBrush
= ( isHighlighted
) ? hiBrush
: lowBrush
;
1369 Draw3DRect( rect
, dc
, curBrush
);
1371 if ( mpPane
->IsHorizontal() )
1374 triRect
.y
= rect
.y
+ TRIANGLE_OFFSET
;
1376 triRect
.width
= rect
.width
;
1377 triRect
.height
= ICON_TRIAN_HEIGHT
;
1379 DrawTrianDown( triRect
, dc
);
1382 patRect
.x
= rect
.x
+ PAT_OFFSET
;
1383 patRect
.y
= rect
.y
+ TRIANGLE_OFFSET
+ ICON_TRIAN_HEIGHT
+ TRIANGLE_TO_PAT_GAP
;
1384 patRect
.width
= rect
.width
- 2*PAT_OFFSET
;
1385 patRect
.height
= rect
.height
- ( patRect
.y
- rect
.y
) - PAT_OFFSET
;
1386 Draw3DPattern( patRect
, dc
);
1388 dc
.SetPen( mpLayout
->mLightPen
);
1389 dc
.DrawLine( rect
.x
, rect
.y
+ rect
.height
, rect
.x
+ rect
.width
, rect
.y
+ rect
.height
);
1394 triRect
.x
= rect
.x
+ TRIANGLE_OFFSET
;
1396 triRect
.height
= rect
.height
;
1397 triRect
.width
= ICON_TRIAN_HEIGHT
;
1399 DrawTrianRight( triRect
, dc
);
1402 patRect
.y
= rect
.y
+ PAT_OFFSET
;
1403 patRect
.x
= rect
.x
+ TRIANGLE_OFFSET
+ ICON_TRIAN_HEIGHT
+ TRIANGLE_TO_PAT_GAP
;
1404 patRect
.height
= rect
.height
- 2*PAT_OFFSET
;
1405 patRect
.width
= rect
.width
- ( patRect
.x
- rect
.x
) - PAT_OFFSET
;
1406 Draw3DPattern( patRect
, dc
);
1408 dc
.SetPen( mpLayout
->mLightPen
);
1409 dc
.DrawLine( rect
.x
+ rect
.width
, rect
.y
, rect
.x
+ rect
.width
, rect
.y
+ rect
.height
);
1413 void cbRowDragPlugin::DrawRowsDragHintsBorder( wxDC
& dc
)
1415 // FIXME:: what was that?
1418 void cbRowDragPlugin::DrawCollapsedRowsBorder( wxDC
& dc
)
1420 int colRowOfs
= GetCollapsedIconsPos();
1421 wxRect
& bounds
= mpPane
->mBoundsInParent
;
1423 wxBrush
bkBrush( mpLayout
->mGrayPen
.GetColour(), wxSOLID
);
1424 dc
.SetBrush( bkBrush
);
1425 dc
.SetPen( mpLayout
->mDarkPen
);
1427 if ( mpPane
->IsHorizontal() )
1429 dc
.DrawRectangle( bounds
.x
+ mpPane
->mLeftMargin
- ROW_DRAG_HINT_WIDTH
- 1,
1431 bounds
.width
- mpPane
->mLeftMargin
- mpPane
->mRightMargin
+ 2 + ROW_DRAG_HINT_WIDTH
,
1432 COLLAPSED_ICON_HEIGHT
+ 1);
1434 dc
.DrawRectangle( colRowOfs
,
1435 bounds
.y
+ mpPane
->mTopMargin
- 1,
1436 COLLAPSED_ICON_HEIGHT
+ 1,
1437 bounds
.height
- mpPane
->mTopMargin
- mpPane
->mBottomMargin
1438 - ROW_DRAG_HINT_WIDTH
- 2 );
1440 dc
.SetBrush( wxNullBrush
);
1443 static inline bool rect_contains_point( const wxRect
& rect
, int x
, int y
)
1445 return ( x
>= rect
.x
&&
1447 x
< rect
.x
+ rect
.width
&&
1448 y
< rect
.y
+ rect
.height
);
1451 bool cbRowDragPlugin::HitTestCollapsedRowIcon( int iconIdx
, const wxPoint
& pos
)
1454 GetCollapsedInconRect( iconIdx
, bounds
);
1456 return rect_contains_point( bounds
, pos
.x
, pos
.y
);
1459 bool cbRowDragPlugin::HitTestRowDragHint( cbRowInfo
* pRow
, const wxPoint
& pos
)
1462 GetRowHintRect( pRow
, bounds
);
1464 return rect_contains_point( bounds
, pos
.x
, pos
.y
);