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