]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/fl/rowdragpl.cpp
fixes for animated GIFs playing (patch 1097003)
[wxWidgets.git] / contrib / src / fl / rowdragpl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: rowdragpl.cpp
3 // Purpose: cbRowDragPlugin implementation.
4 // Author: Aleksandras Gluchovas
5 // Modified by:
6 // Created: 06/10/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Aleksandras Gluchovas
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "rowdragpl.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/wx.h"
25 #endif
26
27 #include "wx/fl/rowdragpl.h"
28
29 #define MINIMAL_ROW_DRAG_OFS 5
30
31 // parameters for row-hints of NC-look
32
33 #define TRIANGLE_OFFSET 2
34 #define TRIANGLE_TO_PAT_GAP 2
35 #define PAT_OFFSET 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
41
42 /***** Implementation for class cbHiddenBarInfo *****/
43
44 IMPLEMENT_DYNAMIC_CLASS( cbHiddenBarInfo, wxObject )
45
46 /***** Implementation for class cbRowDragPlugin *****/
47
48 IMPLEMENT_DYNAMIC_CLASS( cbRowDragPlugin, cbPluginBase )
49
50 BEGIN_EVENT_TABLE( cbRowDragPlugin, cbPluginBase )
51
52 EVT_PL_LEFT_DOWN ( cbRowDragPlugin::OnLButtonDown )
53 EVT_PL_LEFT_UP ( cbRowDragPlugin::OnLButtonUp )
54 EVT_PL_MOTION ( cbRowDragPlugin::OnMouseMove )
55
56 EVT_PL_DRAW_PANE_DECOR ( cbRowDragPlugin::OnDrawPaneBackground )
57
58 END_EVENT_TABLE()
59
60 // FIXME:: how to eliminated these cut and pasted constructors?
61
62 cbRowDragPlugin::cbRowDragPlugin(void)
63
64 : mHightColor ( 192, 192, 255 ),
65 mLowColor ( 192, 192, 192 ),
66 mTrianInnerColor ( 0,0,255 ),
67 mTrianInnerPen ( mTrianInnerColor, 1, wxSOLID ),
68
69 mDragStarted ( false ),
70 mDecisionMode ( false ),
71 mCurDragOfs ( 0 ),
72 mCaptureIsOn ( false ),
73 mSvTopMargin ( -1 ),
74 mSvBottomMargin ( -1 ),
75 mSvLeftMargin ( -1 ),
76 mSvRightMargin ( -1 ),
77
78 mpPaneImage ( NULL ),
79 mpRowImage ( NULL ),
80 mpCombinedImage ( NULL ),
81
82 mpRowInFocus ( NULL ),
83 mCollapsedIconInFocus( -1 ),
84
85 mpPane ( NULL )
86 {
87 }
88
89 cbRowDragPlugin::cbRowDragPlugin( wxFrameLayout* pLayout, int paneMask )
90
91 : cbPluginBase( pLayout, paneMask ),
92
93 mHightColor ( 192, 192, 255 ),
94 mLowColor ( 192, 192, 192 ),
95 mTrianInnerColor ( 0,0,255 ),
96 mTrianInnerPen ( mTrianInnerColor, 1, wxSOLID ),
97
98 mDragStarted ( false ),
99 mDecisionMode ( false ),
100 mCurDragOfs ( 0 ),
101 mCaptureIsOn ( false ),
102 mSvTopMargin ( -1 ),
103 mSvBottomMargin ( -1 ),
104 mSvLeftMargin ( -1 ),
105 mSvRightMargin ( -1 ),
106
107 mpPaneImage ( NULL ),
108 mpRowImage ( NULL ),
109 mpCombinedImage ( NULL ),
110
111 mpRowInFocus ( NULL ),
112 mCollapsedIconInFocus( -1 ),
113
114 mpPane ( NULL )
115 {
116 }
117
118 cbRowDragPlugin::~cbRowDragPlugin()
119 {
120 }
121
122 // handlers for plugin events
123 void cbRowDragPlugin::OnMouseMove( cbMotionEvent& event )
124 {
125 // short-cuts
126 wxPoint pos = event.mPos;
127 mpPane = event.mpPane;
128
129 mpPane->PaneToFrame( &pos.x, &pos.y );
130
131 if ( !mDragStarted )
132 {
133 if ( mDecisionMode && mpRowInFocus )
134 {
135 int ofs;
136
137 if ( mpPane->IsHorizontal() )
138
139 ofs = pos.y - mDragOrigin.y;
140 else
141 ofs = pos.x - mDragOrigin.x;
142
143 // check if the item was dragged sufficeintly
144 // far, enough to consider that user really intends
145 // to drag it
146
147 if ( ofs >= MINIMAL_ROW_DRAG_OFS ||
148 ofs <= -MINIMAL_ROW_DRAG_OFS )
149 {
150 // DBG::
151 //.wxPoint pos = event.mPos;
152 //wxPoint drg = mDragOrigin;
153 //int dif = event.mPos.x - mDragOrigin.x;
154
155 mDragStarted = true;
156 mDecisionMode = false;
157 mDragOrigin = pos;
158
159 PrepareForRowDrag();
160 return;
161 }
162
163 // this plugin "eats" all mouse input while item is dragged,
164 return;
165 }
166
167 cbRowInfo* pRow = GetFirstRow();
168
169 bool focusFound = false;
170
171 while( pRow )
172 {
173 if ( HitTestRowDragHint( pRow, pos ) )
174 {
175 CheckPrevItemInFocus( pRow, -1 );
176 SetMouseCapture( true );
177
178 focusFound = true;
179
180 mpRowInFocus = pRow;
181 mCollapsedIconInFocus = -1;
182 break;
183 }
184
185 pRow = pRow->mpNext;
186 }
187
188 if ( !focusFound )
189 {
190 int hrCnt = GetHRowsCountForPane( event.mpPane );
191
192 for( int i = 0; i != hrCnt; ++i )
193 {
194 if ( HitTestCollapsedRowIcon( i, pos ) )
195 {
196 CheckPrevItemInFocus( NULL, i );
197 SetMouseCapture( true );
198
199 focusFound = true;
200
201 mCollapsedIconInFocus = i;
202 mpRowInFocus = NULL;
203 break;
204 }
205 }
206 }
207
208 if ( !focusFound && ItemIsInFocus() )
209 {
210 // kill focus from item previously been in focus
211 UnhighlightItemInFocus();
212
213 mpRowInFocus = NULL;
214 mCollapsedIconInFocus = -1;
215 SetMouseCapture( false );
216 }
217
218 if ( !ItemIsInFocus() )
219
220 // delegate it to other plugins
221 event.Skip();
222 }
223 else
224 {
225 // otherwise mouse pointer moves, when dragging is started
226
227 if ( mpPane->IsHorizontal() )
228 {
229 // row is dragged up or down;
230 ShowDraggedRow( pos.y - mDragOrigin.y );
231 }
232 else
233 {
234 // row is dragged left or right
235 ShowDraggedRow( pos.x - mDragOrigin.x );
236 }
237
238 // this plugin "eats" all mouse input while item is dragged,
239 }
240 }
241
242 void cbRowDragPlugin::OnLButtonDown( cbLeftDownEvent& event )
243 {
244 mpPane = event.mpPane;
245
246 // DBG::
247 wxASSERT( !mDragStarted && !mDecisionMode );
248
249 if ( ItemIsInFocus() )
250 {
251 mDecisionMode = true;
252
253 wxPoint pos = event.mPos;
254 mpPane->PaneToFrame( &pos.x, &pos.y );
255
256 mDragOrigin = pos;
257
258 SetMouseCapture( true );
259 }
260 else
261 // propagate event to other plugins
262 event.Skip();
263 }
264
265 void cbRowDragPlugin::OnLButtonUp ( cbLeftUpEvent& event )
266 {
267 if ( !mDragStarted && !mDecisionMode )
268 {
269 event.Skip();
270 return;
271 }
272
273 mpPane = event.mpPane;
274
275 if ( mDecisionMode )
276 {
277 cbDockPane* pPane = mpPane;
278
279 SetMouseCapture( false );
280
281 mDecisionMode = false;
282 mDragStarted = false;
283
284 wxPoint frmPos = event.mPos;
285 pPane->PaneToFrame( &frmPos.x, &frmPos.y );
286
287 if ( mpRowInFocus )
288 {
289 CollapseRow( mpRowInFocus );
290 mpRowInFocus = 0;
291 }
292 else
293 {
294 ExpandRow( mCollapsedIconInFocus );
295 mCollapsedIconInFocus = -1;
296 }
297
298 mpRowInFocus = NULL;
299 mpPane = pPane;
300
301 pPane->FrameToPane( &frmPos.x, &frmPos.y );
302
303 // give it another try after relayouting bars
304
305 cbMotionEvent moveEvt( frmPos, pPane );
306 this->OnMouseMove( moveEvt );
307
308 // this plugin has "eaten" the mouse-up event
309
310 return;
311 }
312 else
313 {
314 // otherwise, the dragged row was dropped, determine
315 // where to insert it
316
317 // restore initial pane appearence
318 ShowPaneImage();
319 FinishOnScreenDraw();
320
321 cbRowInfo* pRow = GetFirstRow();
322
323 mpLayout->GetUpdatesManager().OnStartChanges();
324
325 pRow->mUMgrData.SetDirty(true);
326
327 cbBarInfo* pBar = mpRowInFocus->mBars[0];
328
329 while ( pBar )
330 {
331 pBar->mUMgrData.SetDirty(true);
332
333 if ( pBar->mpBarWnd )
334 {
335 // do complete refresh
336 pBar->mpBarWnd->Show(false);
337 pBar->mpBarWnd->Show(true);
338 }
339
340 pBar = pBar->mpNext;
341 }
342
343 while( pRow )
344 {
345 if ( mCurDragOfs < pRow->mRowY )
346 {
347 InsertDraggedRowBefore( pRow );
348 break;
349 }
350
351 pRow = pRow->mpNext;
352 }
353
354 if ( pRow == NULL ) InsertDraggedRowBefore( NULL );
355
356 mpRowInFocus = NULL;
357
358 mpLayout->RecalcLayout(false);
359
360 // finish change "transaction"
361 mpLayout->GetUpdatesManager().OnFinishChanges();
362 mpLayout->GetUpdatesManager().UpdateNow();
363
364 // finish drag action
365 SetMouseCapture( false );
366 mDragStarted = false;
367 }
368 }
369
370 void cbRowDragPlugin::OnDrawPaneBackground ( cbDrawPaneDecorEvent& event )
371 {
372 mpPane = event.mpPane;
373
374 // FIXME:: this may harm operation of other plugins
375
376 if ( GetNextHandler() && mpPane->GetRowList().GetCount() )
377 {
378 // first, let other plugins add their decorations now
379
380 GetNextHandler()->ProcessEvent( event );
381 event.Skip(false);
382 }
383
384 wxClientDC dc( &mpLayout->GetParentFrame() );
385
386 dc.SetClippingRegion( mpPane->mBoundsInParent.x,
387 mpPane->mBoundsInParent.y,
388 mpPane->mBoundsInParent.width,
389 mpPane->mBoundsInParent.height );
390
391 int cnt = GetHRowsCountForPane( event.mpPane );
392
393 if ( cnt > 0 )
394
395 DrawCollapsedRowsBorder( dc );
396
397 if ( mpPane->GetRowList().GetCount() )
398
399 DrawRowsDragHintsBorder( dc );
400
401 cbRowInfo* pRow = GetFirstRow();
402
403 while( pRow )
404 {
405 DrawRowDragHint( pRow, dc, false );
406 pRow = pRow->mpNext;
407 }
408
409 for( int i = 0; i != cnt; ++i )
410
411 DrawCollapsedRowIcon(i, dc, false );
412 }
413
414 int cbRowDragPlugin::GetHRowsCountForPane( cbDockPane* pPane )
415 {
416 wxNode* pNode = mHiddenBars.GetFirst();
417
418 int maxIconNo = -1;
419
420 while( pNode )
421 {
422 cbHiddenBarInfo* pHBInfo = (cbHiddenBarInfo*)pNode->GetData();
423
424 if ( pHBInfo->mAlignment == pPane->mAlignment )
425
426 maxIconNo = wxMax( maxIconNo, pHBInfo->mIconNo );
427
428 pNode = pNode->GetNext();
429 }
430
431 return ( maxIconNo + 1 );
432 }
433
434 int cbRowDragPlugin::GetCollapsedRowIconHeight()
435 {
436 return COLLAPSED_ICON_HEIGHT;
437 }
438
439 int cbRowDragPlugin::GetRowDragHintWidth()
440 {
441 return ROW_DRAG_HINT_WIDTH;
442 }
443
444 void cbRowDragPlugin::SetPaneMargins()
445 {
446 int hiddenRowsCnt = GetHRowsCountForPane( mpPane );
447
448 if ( mSvTopMargin == -1 )
449 {
450 mSvTopMargin = mpPane->mTopMargin;
451 mSvBottomMargin = mpPane->mBottomMargin;
452 mSvLeftMargin = mpPane->mLeftMargin;
453 mSvRightMargin = mpPane->mRightMargin;
454 }
455
456 if ( mpPane->IsHorizontal() )
457 {
458 mpPane->mTopMargin = mSvTopMargin;
459 mpPane->mBottomMargin = ( hiddenRowsCnt == 0 )
460 ? mSvBottomMargin
461 : mSvBottomMargin + GetCollapsedRowIconHeight();
462
463 mpPane->mLeftMargin = mSvLeftMargin + GetRowDragHintWidth();
464 mpPane->mRightMargin = mSvRightMargin;
465 }
466 else
467 {
468 mpPane->mTopMargin = mSvTopMargin;
469 mpPane->mBottomMargin = mSvBottomMargin + GetRowDragHintWidth();
470
471 mpPane->mLeftMargin = mSvLeftMargin;
472 mpPane->mRightMargin = ( hiddenRowsCnt == 0 ) ?
473 mSvRightMargin : mSvRightMargin + GetCollapsedRowIconHeight();
474 }
475 }
476
477 void cbRowDragPlugin::OnInitPlugin()
478 {
479 cbDockPane** panes = mpLayout->GetPanesArray();
480
481 for( int i = 0; i != MAX_PANES; ++i )
482
483 if ( panes[i]->MatchesMask( mPaneMask ) )
484 {
485 mpPane = panes[i];
486
487 SetPaneMargins();
488 }
489 }
490
491 /*** helpers for drag&drop ***/
492
493 void cbRowDragPlugin::SetMouseCapture( bool captureOn )
494 {
495 if ( mCaptureIsOn == captureOn ) return;
496
497 if ( captureOn )
498 {
499 mpLayout->CaptureEventsForPane( mpPane );
500 mpLayout->CaptureEventsForPlugin( this );
501 }
502 else
503 {
504 mpLayout->ReleaseEventsFromPane( mpPane );
505 mpLayout->ReleaseEventsFromPlugin( this );
506 }
507
508 mCaptureIsOn = captureOn;
509 }
510
511 void cbRowDragPlugin::UnhighlightItemInFocus()
512 {
513 wxClientDC dc( &mpLayout->GetParentFrame() );
514
515 if ( mpRowInFocus )
516
517 DrawRowDragHint( mpRowInFocus, dc, false );
518 else
519 if ( mCollapsedIconInFocus != - 1 )
520
521 DrawCollapsedRowIcon( mCollapsedIconInFocus, dc, false );
522 }
523
524 void cbRowDragPlugin::ShowDraggedRow( int offset )
525 {
526 // create combined image of pane and dragged
527 // row on it, in the mpCombinedImage bitmap
528
529 if ( mpPane->IsHorizontal() )
530 {
531 if ( mInitialRowOfs + offset + mRowImgDim.y > mCombRect.y + mCombRect.height )
532
533 offset = mCombRect.y + mCombRect.height - mRowImgDim.y - mInitialRowOfs;
534
535 if ( mInitialRowOfs + offset < mCombRect.y )
536
537 offset = mCombRect.y - mInitialRowOfs;
538
539 int x, y = mInitialRowOfs + offset;
540 mpPane->FrameToPane( &x, &y );
541 mCurDragOfs = y;
542 }
543 else
544 {
545 if ( mInitialRowOfs + offset + mRowImgDim.x > mCombRect.x + mCombRect.width )
546
547 offset = mCombRect.x + mCombRect.width - mRowImgDim.x - mInitialRowOfs;
548
549 if ( mInitialRowOfs + offset < mCombRect.x )
550
551 offset = mCombRect.x - mInitialRowOfs;
552
553 int x = mInitialRowOfs + offset, y;
554 mpPane->FrameToPane( &x, &y );
555 mCurDragOfs = x;
556 }
557
558 wxMemoryDC rowImgDc;
559 rowImgDc.SelectObject ( *mpRowImage );
560
561 wxMemoryDC paneImgDc;
562 paneImgDc.SelectObject( *mpPaneImage );
563
564 wxMemoryDC combImgDc;
565 combImgDc.SelectObject( *mpCombinedImage );
566
567 combImgDc.Blit( 0,0, mCombRect.width, mCombRect.height,
568 &paneImgDc, 0,0, wxCOPY );
569
570 if ( mpPane->IsHorizontal() )
571 {
572 combImgDc.Blit( 0, mInitialRowOfs + offset - mCombRect.y,
573 mCombRect.width, mRowImgDim.y,
574 &rowImgDc, 0,0, wxCOPY );
575 }
576 else
577 {
578 combImgDc.Blit( mInitialRowOfs + offset - mCombRect.x,
579 0,
580 mRowImgDim.x, mCombRect.height,
581 &rowImgDc, 0,0, wxCOPY );
582 }
583
584 int scrX = mCombRect.x,
585 scrY = mCombRect.y;
586
587 mpLayout->GetParentFrame().ClientToScreen( &scrX, &scrY );
588
589 mpScrDc->Blit( scrX, scrY, mCombRect.width, mCombRect.height,
590 &combImgDc, 0,0, wxCOPY );
591
592 rowImgDc .SelectObject( wxNullBitmap );
593 paneImgDc.SelectObject( wxNullBitmap );
594 combImgDc.SelectObject( wxNullBitmap );
595 }
596
597 wxBitmap* cbRowDragPlugin::CaptureDCArea( wxDC& dc, wxRect& area )
598 {
599 wxBitmap* pBmp = new wxBitmap( int(area.width), int(area.height) );
600
601 wxMemoryDC mdc;
602 mdc.SelectObject( *pBmp );
603
604 mdc.Blit( 0,0, area.width, area.height, &dc, area.x, area.y, wxCOPY );
605 mdc.SelectObject( wxNullBitmap );
606
607 return pBmp;
608 }
609
610 void cbRowDragPlugin::PrepareForRowDrag()
611 {
612 wxRect rowBounds = mpRowInFocus->mBoundsInParent;
613
614 if ( mpPane->IsHorizontal() )
615 {
616 mCombRect = mpPane->mBoundsInParent;
617
618 mCombRect.x += mpPane->mLeftMargin - ROW_DRAG_HINT_WIDTH - 1;
619 mCombRect.y += mpPane->mTopMargin;
620
621 mCombRect.width -= mpPane->mLeftMargin + mpPane->mRightMargin - ROW_DRAG_HINT_WIDTH - 1 - 1;
622 mCombRect.height -= mpPane->mTopMargin + mpPane->mBottomMargin;
623
624 mCombRect.height += 2*rowBounds.height;
625 mCombRect.y -= rowBounds.height;
626 mInitialRowOfs = rowBounds.y;
627
628 rowBounds.y -= 1;
629 rowBounds.height += 2;
630 rowBounds.x = mCombRect.x;
631 rowBounds.width = mCombRect.width;
632
633 mRowImgDim.y = rowBounds.height;
634 }
635 else
636 {
637 mCombRect = mpPane->mBoundsInParent;
638
639 mCombRect.y += mpPane->mTopMargin - 1;
640 mCombRect.x += mpPane->mLeftMargin - 1;
641 ;
642 mCombRect.height -= mpPane->mTopMargin + mpPane->mBottomMargin - ROW_DRAG_HINT_WIDTH - 1 - 1;
643 mCombRect.width -= mpPane->mLeftMargin + mpPane->mRightMargin;
644
645 mCombRect.width += 2*rowBounds.width;
646 mCombRect.x -= rowBounds.width;
647 mInitialRowOfs = rowBounds.x;
648
649 rowBounds.x -= 1;
650 rowBounds.width += 2;
651 rowBounds.y = mCombRect.y;
652 rowBounds.height = mCombRect.height;
653
654 mRowImgDim.x = rowBounds.width;
655 }
656 // output cobination results onto frame's client area
657 wxScreenDC::StartDrawingOnTop(&mpLayout->GetParentFrame());
658 mpScrDc = new wxScreenDC();
659
660 int x = mCombRect.x, y = mCombRect.y;
661 mpLayout->GetParentFrame().ClientToScreen( &x, &y );
662
663 wxRect scrRect = mCombRect;
664 scrRect.x = x;
665 scrRect.y = y;
666
667 mpPaneImage = CaptureDCArea( *mpScrDc, scrRect );
668
669 wxMemoryDC mdc;
670 mdc.SelectObject( *mpPaneImage );
671 mdc.SetDeviceOrigin( -mCombRect.x, -mCombRect.y );
672
673 DrawRectShade( rowBounds, mdc, -1, mpLayout->mGrayPen, mpLayout->mDarkPen );
674 DrawRectShade( rowBounds, mdc, 0, mpLayout->mLightPen, mpLayout->mBlackPen );
675
676 mpRowImage = CaptureDCArea( mdc, rowBounds );
677
678 // draw dark empty-row placeholder
679 DrawEmptyRow( mdc, rowBounds );
680
681 //DrawRectShade( rowBounds, mdc, 0, mpLayout->mGrayPen, mpLayout->mDarkPen );
682 DrawRectShade( rowBounds, mdc, -1, mpLayout->mGrayPen, mpLayout->mGrayPen );
683
684 mdc.SelectObject( wxNullBitmap );
685
686 mpCombinedImage = new wxBitmap( int(mCombRect.width), int(mCombRect.height) );
687
688 // show it for the first time
689 ShowDraggedRow( 0 );
690 }
691
692 void cbRowDragPlugin::DrawEmptyRow( wxDC& dc, wxRect& rowBounds )
693 {
694 wxBrush bkBrush( mpLayout->mDarkPen.GetColour(), wxSOLID );
695
696 // paint the "dark" empty-row placeholder
697
698 dc.SetBrush( bkBrush );
699 dc.SetPen ( mpLayout->mNullPen );
700
701 dc.DrawRectangle( rowBounds.x, rowBounds.y,
702 rowBounds.width+1, rowBounds.height+1 );
703
704 dc.SetBrush( wxNullBrush );
705 }
706
707 void cbRowDragPlugin::ShowPaneImage()
708 {
709 int scrX = 0, scrY = 0;
710
711 mpLayout->GetParentFrame().ClientToScreen( &scrX, &scrY );
712
713 wxMemoryDC mdc;
714 mdc.SelectObject( *mpPaneImage );
715
716 mpScrDc->Blit( mCombRect.x + scrX, mCombRect.y + scrY,
717 mCombRect.width, mCombRect.height,
718 &mdc, 0,0, wxCOPY );
719
720 mdc.SelectObject( wxNullBitmap );
721 }
722
723 void cbRowDragPlugin::FinishOnScreenDraw()
724 {
725 wxScreenDC::EndDrawingOnTop();
726
727 delete mpScrDc;
728 delete mpCombinedImage;
729 delete mpPaneImage;
730 delete mpRowImage;
731
732 mpScrDc = NULL;
733
734 mpCombinedImage = mpPaneImage = mpRowImage = NULL;
735 }
736
737 void cbRowDragPlugin::CollapseRow( cbRowInfo* pRow )
738 {
739 int iconCnt = GetHRowsCountForPane( mpPane );
740
741 mpLayout->GetUpdatesManager().OnStartChanges();
742
743 cbBarInfo* pBar = pRow->mBars[0];
744
745 int rowNo = 0;
746
747 cbRowInfo* pCur = pRow;
748 while( pCur->mpPrev ) { ++rowNo; pCur = pCur->mpPrev; }
749
750 while( pBar )
751 {
752 cbHiddenBarInfo* pHBInfo = new cbHiddenBarInfo();
753
754 pHBInfo->mpBar = pBar;
755 pHBInfo->mRowNo = rowNo;
756 pHBInfo->mIconNo = iconCnt;
757 pHBInfo->mAlignment = mpPane->mAlignment;
758
759 mHiddenBars.Append( (wxObject*) pHBInfo );
760
761 // hide it
762 if ( pBar->mpBarWnd )
763
764 pBar->mpBarWnd->Show( false );
765
766 pBar->mState = wxCBAR_HIDDEN;
767
768 cbBarInfo* pNext = pBar->mpNext;
769
770 pBar->mpRow = NULL;
771 pBar->mpNext = NULL;
772 pBar->mpPrev = NULL;
773
774 pBar = pNext;
775 }
776
777 mpPane->GetRowList().Remove( pRow );
778 mpPane->InitLinksForRows();
779
780 delete pRow;
781
782 SetPaneMargins();
783
784 mpLayout->RecalcLayout(false);
785
786 mpRowInFocus = NULL;
787
788 mpLayout->GetUpdatesManager().OnFinishChanges();
789 mpLayout->GetUpdatesManager().UpdateNow();
790 }
791
792 void cbRowDragPlugin::ExpandRow( int collapsedIconIdx )
793 {
794 mpLayout->GetUpdatesManager().OnStartChanges();
795
796 cbRowInfo* pNewRow = new cbRowInfo();
797
798 wxNode* pNode = mHiddenBars.GetFirst();
799
800 int rowNo = 0;
801
802 // move bars from internal list to the newly expanded row
803
804 while( pNode )
805 {
806 cbHiddenBarInfo* pHBInfo = (cbHiddenBarInfo*)pNode->GetData();
807
808 if ( pHBInfo->mAlignment == mpPane->mAlignment &&
809 pHBInfo->mIconNo == collapsedIconIdx )
810 {
811 rowNo = pHBInfo->mRowNo;
812
813 if ( pHBInfo->mpBar->mState == wxCBAR_HIDDEN )
814 {
815 pNewRow->mBars.Add( pHBInfo->mpBar );
816
817 pHBInfo->mpBar->mState = ( mpPane->IsHorizontal() )
818 ? wxCBAR_DOCKED_HORIZONTALLY
819 : wxCBAR_DOCKED_VERTICALLY;
820 }
821
822 // remove bar info from internal list
823
824 wxNode* pNext = pNode->GetNext();
825
826 delete pHBInfo;
827 mHiddenBars.DeleteNode( pNode );
828
829 pNode = pNext;
830 }
831 else
832 {
833 // decrease incon numbers with higher indicies, since this
834 // row is now removed from the hidden-rows list
835
836 if ( pHBInfo->mIconNo > collapsedIconIdx &&
837 pHBInfo->mAlignment == mpPane->mAlignment )
838
839 --pHBInfo->mIconNo;
840
841 pNode = pNode->GetNext();
842 }
843 }
844
845 mpPane->InitLinksForRow( pNewRow );
846
847 // insert row into pane at it's original position
848
849 if ( pNewRow->mBars.GetCount() )
850 {
851 cbRowInfo* beforeRowNode = mpPane->GetRow( rowNo );
852
853 mpPane->InsertRow( pNewRow, beforeRowNode );
854 }
855 else
856 delete pNewRow;
857
858 SetPaneMargins();
859
860 mpLayout->RecalcLayout(false);
861
862 mCollapsedIconInFocus = -1;
863
864 mpLayout->GetUpdatesManager().OnFinishChanges();
865 mpLayout->GetUpdatesManager().UpdateNow();
866
867
868 /*
869 wxNode* pRowNode = mHiddenRows.Nth( collapsedIconIdx );
870
871 mpLayout->GetUpdatesManager().OnStartChanges();
872
873 // insert at the end of rows list
874 mpPane->InsertRow( pRowNode, NULL );
875
876 int success = mHiddenRows.DeleteNode( pRowNode );
877 // DBG::
878 wxASSERT( success );
879
880 SetPaneMargins();
881
882 mpLayout->RecalcLayout(false);
883
884 mCollapsedIconInFocus = -1;
885
886 mpLayout->GetUpdatesManager().OnFinishChanges();
887 mpLayout->GetUpdatesManager().UpdateNow();
888 */
889 }
890
891 void cbRowDragPlugin::InsertDraggedRowBefore( cbRowInfo* pBeforeRow )
892 {
893 if ( mpRowInFocus != pBeforeRow &&
894 mpRowInFocus->mpNext != pBeforeRow
895 )
896 {
897 mpPane->GetRowList().Remove( mpRowInFocus );
898
899 mpPane->InsertRow( mpRowInFocus, pBeforeRow );
900 }
901 else
902 {
903 // otherwise, nothing has happned (row positions do not change)
904
905 //wxClientDC dc( &mpLayout->GetParentFrame() );
906
907 //mpPane->PaintRow( mpRowInFocus, dc );
908 //DrawRowDragHint( mpRowInFocus, dc, false );
909 }
910 }
911
912 bool cbRowDragPlugin::ItemIsInFocus()
913 {
914 return ( mpRowInFocus || mCollapsedIconInFocus != - 1 );
915 }
916
917 void cbRowDragPlugin::CheckPrevItemInFocus( cbRowInfo* pRow, int iconIdx )
918 {
919 wxClientDC dc( &mpLayout->GetParentFrame() );
920
921 if ( pRow != NULL && mpRowInFocus == pRow ) return;
922 if ( iconIdx != -1 && mCollapsedIconInFocus == iconIdx ) return;
923
924 UnhighlightItemInFocus();
925
926 if ( iconIdx != - 1 )
927
928 DrawCollapsedRowIcon( iconIdx, dc, true );
929
930 else
931 if ( pRow != NULL )
932
933 DrawRowDragHint( pRow, dc, true );
934 }
935
936 cbRowInfo* cbRowDragPlugin::GetFirstRow()
937 {
938 return ( mpPane->GetRowList().GetCount() )
939 ? mpPane->GetRowList()[0]
940 : NULL;
941 }
942
943 /*** "hard-coded" metafile for NN-look ***/
944
945 void cbRowDragPlugin::DrawTrianUp( wxRect& inRect, wxDC& dc )
946 {
947 int xOfs = (inRect.width - ICON_TRIAN_WIDTH)/2;
948
949 wxBrush br( mTrianInnerColor, wxSOLID );
950
951 dc.SetBrush( br );
952 dc.SetPen( mpLayout->mBlackPen );
953
954 wxPoint points[3];
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;
961
962 dc.DrawPolygon( 3, points );
963
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 );
968
969 dc.SetBrush( wxNullBrush );
970 }
971
972 void cbRowDragPlugin::DrawTrianDown( wxRect& inRect, wxDC& dc )
973 {
974 int xOfs = (inRect.width - ICON_TRIAN_WIDTH)/2;
975
976 wxBrush br( mTrianInnerColor, wxSOLID );
977
978 dc.SetBrush( br );
979 dc.SetPen( mpLayout->mBlackPen );
980
981 wxPoint points[3];
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;
988
989 dc.DrawPolygon( 3, points );
990
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 );
995
996 dc.SetBrush( wxNullBrush );
997 }
998
999 void cbRowDragPlugin::DrawTrianRight( wxRect& inRect, wxDC& dc )
1000 {
1001 int yOfs = (inRect.height - ICON_TRIAN_WIDTH)/2;
1002
1003 wxBrush br( mTrianInnerColor, wxSOLID );
1004
1005 dc.SetBrush( br );
1006 dc.SetPen( mpLayout->mBlackPen );
1007
1008 wxPoint points[3];
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;
1015
1016 dc.DrawPolygon( 3, points );
1017
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 );
1022
1023 dc.SetBrush( wxNullBrush );
1024 }
1025
1026 void cbRowDragPlugin::Draw3DPattern( wxRect& inRect, wxDC& dc )
1027 {
1028 for( int y = inRect.y; y < inRect.y + inRect.height; y+=3 )
1029
1030 for( int x = inRect.x; x < inRect.x + inRect.width; x+=3 )
1031 {
1032 dc.SetPen( mpLayout->mLightPen );
1033 dc.DrawPoint( x,y );
1034 dc.SetPen( mpLayout->mBlackPen );
1035 dc.DrawPoint( x+1, y+1 );
1036 }
1037 }
1038
1039 void cbRowDragPlugin::DrawRombShades( wxPoint& p1, wxPoint& p2,
1040 wxPoint& p3, wxPoint& p4,
1041 wxDC& dc )
1042 {
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 );
1049 }
1050
1051 void cbRowDragPlugin::DrawOrtoRomb( wxRect& inRect, wxDC& dc, wxBrush& bkBrush )
1052 {
1053 dc.SetBrush( bkBrush );
1054 dc.SetPen( mpLayout->mBlackPen );
1055
1056 wxPoint points[4];
1057
1058 if ( inRect.width > inRect.height )
1059 {
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;
1069
1070 dc.DrawPolygon( 4, points );
1071
1072 // squeeze romb's bounds to create an inner-shade shape
1073 ++points[0].x;
1074 --points[0].y;
1075 ++points[1].x;
1076 ++points[1].y;
1077 --points[2].x; --points[2].x;
1078 ++points[2].y;
1079 --points[3].y;
1080
1081 DrawRombShades( points[0], points[1], points[2], points[3], dc );
1082 }
1083 else
1084 {
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;
1094
1095 dc.DrawPolygon( 4, points );
1096
1097 // squeeze romb's bounds to create an inner-shade shape
1098 --points[0].y ;
1099 --points[0].x;
1100 ++points[1].x;
1101 --points[1].y;
1102 ++points[2].y; ++points[2].y;
1103 ++points[2].x;
1104 --points[3].x;
1105
1106 DrawRombShades( points[1], points[2], points[3], points[0], dc );
1107 }
1108
1109 dc.SetBrush( wxNullBrush );
1110 }
1111
1112 void cbRowDragPlugin::DrawRomb( wxRect& inRect, wxDC& dc, wxBrush& bkBrush )
1113 {
1114 wxPoint points[4];
1115
1116 dc.SetBrush( bkBrush );
1117 dc.SetPen( mpLayout->mBlackPen );
1118
1119 if ( inRect.width > inRect.height )
1120 {
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;
1130
1131 dc.DrawPolygon( 4, points );
1132
1133 // squeeze romb's bounds to create an inner-shade shape
1134 ++points[0].x ;++points[0].x ;
1135 --points[0].y;
1136 ++points[1].y;
1137 --points[2].x; --points[2].x;
1138 ++points[2].y;
1139 //--points[3].x ;
1140 --points[3].y;
1141
1142 DrawRombShades( points[0], points[1], points[2], points[3], dc );
1143
1144 }
1145 else
1146 {
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;
1156
1157 dc.DrawPolygon( 4, points );
1158
1159 // squeeze romb's bounds to create an inner-shade shape
1160 --points[0].y ;--points[0].y ;
1161 --points[0].x;
1162 ++points[1].x;
1163 ++points[2].y; ++points[2].y;
1164 ++points[2].x;
1165 --points[3].x;
1166
1167 DrawRombShades( points[1], points[2], points[3], points[0], dc );
1168 }
1169
1170 dc.SetBrush( wxNullBrush );
1171 }
1172
1173 void cbRowDragPlugin::DrawRectShade( wxRect& inRect, wxDC& dc,
1174 int level, wxPen& upperPen, wxPen& lowerPen )
1175 {
1176 // upper shade
1177 dc.SetPen( upperPen );
1178 dc.DrawLine( inRect.x - level,
1179 inRect.y - level,
1180 inRect.x + inRect.width - 1 + level,
1181 inRect.y - level);
1182 dc.DrawLine( inRect.x - level, inRect.y - level,
1183 inRect.x - level, inRect.y + inRect.height - 1 + level );
1184
1185 // lower shade
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,
1192 inRect.y - level,
1193 inRect.x + inRect.width - 1 + level,
1194 inRect.y + inRect.height + level);
1195
1196 dc.SetBrush( wxNullBrush );
1197 }
1198
1199 void cbRowDragPlugin::Draw3DRect( wxRect& inRect, wxDC& dc, wxBrush& bkBrush )
1200 {
1201 dc.SetPen( mpLayout->mNullPen );
1202 dc.SetBrush( bkBrush );
1203
1204 dc.DrawRectangle( inRect.x, inRect.y,
1205 inRect.width, inRect.height );
1206
1207 DrawRectShade( inRect, dc, 0, mpLayout->mLightPen, mpLayout->mDarkPen );
1208 }
1209
1210 int cbRowDragPlugin::GetCollapsedIconsPos()
1211 {
1212 RowArrayT& rows = mpPane->GetRowList();
1213
1214 if ( rows.GetCount() == 0 )
1215 {
1216 if ( mpPane->IsHorizontal() )
1217
1218 return mpPane->mBoundsInParent.y + mpPane->mTopMargin;
1219 else
1220 return mpPane->mBoundsInParent.x + mpPane->mLeftMargin;
1221 }
1222
1223 wxRect& bounds = rows[ rows.GetCount() - 1 ]->mBoundsInParent;
1224
1225 if ( mpPane->IsHorizontal() )
1226
1227 return bounds.y + bounds.height + 1;
1228 else
1229 return bounds.x + bounds.width + 1;
1230
1231 }
1232
1233 void cbRowDragPlugin::GetRowHintRect( cbRowInfo* pRow, wxRect& rect )
1234 {
1235 wxRect& bounds = pRow->mBoundsInParent;
1236
1237 if ( mpPane->IsHorizontal() )
1238 {
1239 rect.x = bounds.x - ROW_DRAG_HINT_WIDTH - 1;
1240 rect.y = bounds.y;
1241 rect.width = ROW_DRAG_HINT_WIDTH;
1242 rect.height = bounds.height;
1243 }
1244 else
1245 {
1246 rect.x = bounds.x;
1247 rect.y = bounds.y + bounds.height + 1;
1248 rect.width = bounds.width;
1249 rect.height = ROW_DRAG_HINT_WIDTH;
1250 }
1251 }
1252
1253 void cbRowDragPlugin::GetCollapsedInconRect( int iconIdx, wxRect& rect )
1254 {
1255 int upper = GetCollapsedIconsPos();
1256
1257 int right = (iconIdx == 0 )
1258 ? 0 : iconIdx * (COLLAPSED_ICON_WIDTH - COLLAPSED_ICON_HEIGHT);
1259
1260 if ( mpPane->IsHorizontal() )
1261 {
1262 rect.x = mpPane->mBoundsInParent.x + mpPane->mLeftMargin - ROW_DRAG_HINT_WIDTH - 1
1263 + right;
1264
1265 rect.y = upper;
1266 rect.width = COLLAPSED_ICON_WIDTH;
1267 rect.height = COLLAPSED_ICON_HEIGHT;
1268 }
1269 else
1270 {
1271 rect.x = upper;
1272 rect.y = mpPane->mBoundsInParent.y + mpPane->mBoundsInParent.height
1273 - mpPane->mBottomMargin + ROW_DRAG_HINT_WIDTH + 1
1274 - right - COLLAPSED_ICON_WIDTH;
1275
1276 rect.height = COLLAPSED_ICON_WIDTH;
1277 rect.width = COLLAPSED_ICON_HEIGHT;
1278 }
1279 }
1280
1281 /*** overridables ***/
1282
1283 void cbRowDragPlugin::DrawCollapsedRowIcon( int index, wxDC& dc, bool isHighlighted )
1284 {
1285 wxRect rect;
1286 GetCollapsedInconRect( index, rect );
1287
1288 wxBrush hiBrush ( mHightColor, wxSOLID );
1289 wxBrush lowBrush( mLowColor, wxSOLID );
1290 wxBrush& curBrush = ( isHighlighted ) ? hiBrush : lowBrush;
1291
1292 if ( mpPane->IsHorizontal() )
1293 {
1294 if ( index == 0 )
1295
1296 DrawOrtoRomb( rect, dc, curBrush );
1297 else
1298 DrawRomb( rect, dc, curBrush );
1299
1300 int triOfs = (index == 0) ? TRIANGLE_OFFSET : TRIANGLE_OFFSET + COLLAPSED_ICON_HEIGHT;
1301
1302 wxRect triRect;
1303 triRect.x = triOfs + rect.x;
1304
1305 triRect.width = ICON_TRIAN_HEIGHT;
1306 triRect.y = rect.y;
1307 triRect.height = rect.height;
1308
1309 DrawTrianRight( triRect, dc );
1310
1311 wxRect patRect;
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;
1316
1317 Draw3DPattern( patRect, dc );
1318 }
1319 else
1320 {
1321 if ( index == 0 )
1322
1323 DrawOrtoRomb( rect, dc, curBrush );
1324 else
1325 DrawRomb( rect, dc, curBrush );
1326
1327 int triOfs = (index == 0)
1328 ? TRIANGLE_OFFSET + ICON_TRIAN_HEIGHT
1329 : TRIANGLE_OFFSET + COLLAPSED_ICON_HEIGHT + ICON_TRIAN_HEIGHT;
1330
1331 wxRect triRect;
1332 triRect.y = rect.y + rect.height - triOfs;
1333 triRect.x = rect.x;
1334 triRect.width = rect.width;
1335 triRect.height = ICON_TRIAN_HEIGHT;
1336
1337 DrawTrianUp( triRect, dc );
1338
1339 wxRect patRect;
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;
1344
1345 Draw3DPattern( patRect, dc );
1346 }
1347 }
1348
1349 void cbRowDragPlugin::DrawRowDragHint( cbRowInfo* pRow , wxDC& dc, bool isHighlighted )
1350 {
1351 wxRect rect;
1352 GetRowHintRect( pRow, rect );
1353
1354 wxBrush hiBrush ( mHightColor, wxSOLID );
1355 wxBrush lowBrush( mLowColor, wxSOLID );
1356 wxBrush& curBrush = ( isHighlighted ) ? hiBrush : lowBrush;
1357
1358 Draw3DRect( rect, dc, curBrush );
1359
1360 if ( mpPane->IsHorizontal() )
1361 {
1362 wxRect triRect;
1363 triRect.y = rect.y + TRIANGLE_OFFSET;
1364 triRect.x = rect.x;
1365 triRect.width = rect.width;
1366 triRect.height = ICON_TRIAN_HEIGHT;
1367
1368 DrawTrianDown( triRect, dc );
1369
1370 wxRect patRect;
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 );
1376
1377 dc.SetPen( mpLayout->mLightPen );
1378 dc.DrawLine( rect.x, rect.y + rect.height, rect.x + rect.width, rect.y + rect.height );
1379 }
1380 else
1381 {
1382 wxRect triRect;
1383 triRect.x = rect.x + TRIANGLE_OFFSET;
1384 triRect.y = rect.y;
1385 triRect.height = rect.height;
1386 triRect.width = ICON_TRIAN_HEIGHT;
1387
1388 DrawTrianRight( triRect, dc );
1389
1390 wxRect patRect;
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 );
1396
1397 dc.SetPen( mpLayout->mLightPen );
1398 dc.DrawLine( rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + rect.height );
1399 }
1400 }
1401
1402 void cbRowDragPlugin::DrawRowsDragHintsBorder( wxDC& WXUNUSED(dc) )
1403 {
1404 // FIXME:: what was that?
1405 }
1406
1407 void cbRowDragPlugin::DrawCollapsedRowsBorder( wxDC& dc )
1408 {
1409 int colRowOfs = GetCollapsedIconsPos();
1410 wxRect& bounds = mpPane->mBoundsInParent;
1411
1412 wxBrush bkBrush( mpLayout->mGrayPen.GetColour(), wxSOLID );
1413 dc.SetBrush( bkBrush );
1414 dc.SetPen( mpLayout->mDarkPen );
1415
1416 if ( mpPane->IsHorizontal() )
1417
1418 dc.DrawRectangle( bounds.x + mpPane->mLeftMargin - ROW_DRAG_HINT_WIDTH - 1,
1419 colRowOfs,
1420 bounds.width - mpPane->mLeftMargin - mpPane->mRightMargin + 2 + ROW_DRAG_HINT_WIDTH,
1421 COLLAPSED_ICON_HEIGHT + 1);
1422 else
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 );
1428
1429 dc.SetBrush( wxNullBrush );
1430 }
1431
1432 static inline bool rect_contains_point( const wxRect& rect, int x, int y )
1433 {
1434 return ( x >= rect.x &&
1435 y >= rect.y &&
1436 x < rect.x + rect.width &&
1437 y < rect.y + rect.height );
1438 }
1439
1440 bool cbRowDragPlugin::HitTestCollapsedRowIcon( int iconIdx, const wxPoint& pos )
1441 {
1442 wxRect bounds;
1443 GetCollapsedInconRect( iconIdx, bounds );
1444
1445 return rect_contains_point( bounds, pos.x, pos.y );
1446 }
1447
1448 bool cbRowDragPlugin::HitTestRowDragHint( cbRowInfo* pRow, const wxPoint& pos )
1449 {
1450 wxRect bounds;
1451 GetRowHintRect( pRow, bounds );
1452
1453 return rect_contains_point( bounds, pos.x, pos.y );
1454 }
1455