home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / contrib / src / fl / rowdragpl.cpp < prev    next >
C/C++ Source or Header  |  2002-01-21  |  41KB  |  1,466 lines

  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: rowdragpl.cpp,v 1.3 2002/01/21 22:34:42 JS Exp $
  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.             // DBG::
  230.             wxPoint p = event.mPos;
  231.             wxPoint d = mDragOrigin;
  232. //            int dif = event.mPos.x - mDragOrigin.x;
  233.  
  234.             // row is dragged up or down;
  235.             ShowDraggedRow( pos.y - mDragOrigin.y );
  236.         }
  237.         else
  238.         {
  239.             // DBG::
  240.             wxPoint p = event.mPos;
  241.             wxPoint d = mDragOrigin;
  242. //            int dif = event.mPos.x - mDragOrigin.x;
  243.  
  244.             // row is dragged left or right
  245.             ShowDraggedRow( pos.x - mDragOrigin.x );
  246.         }
  247.  
  248.         // this plugin "eats" all mouse input while item is dragged,
  249.     }
  250. }
  251.  
  252. void cbRowDragPlugin::OnLButtonDown( cbLeftDownEvent& event )
  253. {
  254.     mpPane = event.mpPane;
  255.  
  256.     // DBG::
  257.     wxASSERT( !mDragStarted && !mDecisionMode );
  258.  
  259.     if ( ItemIsInFocus() )
  260.     {
  261.         mDecisionMode = TRUE;
  262.  
  263.         wxPoint pos = event.mPos;
  264.         mpPane->PaneToFrame( &pos.x, &pos.y );
  265.  
  266.         mDragOrigin = pos;
  267.  
  268.         SetMouseCapture( TRUE );
  269.     }
  270.     else
  271.         // propagate event to other plugins
  272.         event.Skip();
  273. }
  274.  
  275. void cbRowDragPlugin::OnLButtonUp  ( cbLeftUpEvent& event )
  276. {
  277.     if ( !mDragStarted && !mDecisionMode ) 
  278.     {
  279.         event.Skip();
  280.         return;
  281.     }
  282.  
  283.     mpPane = event.mpPane;
  284.  
  285.     if ( mDecisionMode )
  286.     {
  287.         cbDockPane* pPane = mpPane;
  288.  
  289.         SetMouseCapture( FALSE );
  290.  
  291.         mDecisionMode = FALSE;
  292.         mDragStarted  = FALSE;
  293.  
  294.         wxPoint frmPos = event.mPos;
  295.         pPane->PaneToFrame( &frmPos.x, &frmPos.y );
  296.  
  297.         if ( mpRowInFocus ) 
  298.         {
  299.             CollapseRow( mpRowInFocus );
  300.             mpRowInFocus = 0;
  301.         }
  302.         else
  303.         {
  304.             ExpandRow( mCollapsedIconInFocus );
  305.             mCollapsedIconInFocus = -1;
  306.         }
  307.  
  308.         mpRowInFocus  = NULL;
  309.         mpPane = pPane;
  310.  
  311.         pPane->FrameToPane( &frmPos.x, &frmPos.y );
  312.  
  313.         // give it another try after relayouting bars
  314.  
  315.         cbMotionEvent moveEvt( frmPos, pPane );
  316.         this->OnMouseMove( moveEvt );
  317.  
  318.         // this plugin has "eaten" the mouse-up event
  319.  
  320.         return;
  321.     }
  322.     else
  323.     {
  324.         // otherwise, the dragged row was dropped, determine
  325.         // where to insert it
  326.  
  327.         // restore initial pane appearence
  328.         ShowPaneImage();
  329.         FinishOnScreenDraw();
  330.  
  331.         cbRowInfo* pRow = GetFirstRow();
  332.  
  333.         mpLayout->GetUpdatesManager().OnStartChanges();
  334.  
  335.         pRow->mUMgrData.SetDirty(TRUE);
  336.  
  337.         cbBarInfo* pBar = mpRowInFocus->mBars[0];
  338.  
  339.         while ( pBar )
  340.         {
  341.             pBar->mUMgrData.SetDirty(TRUE);
  342.  
  343.             if ( pBar->mpBarWnd )
  344.             {
  345.                 // do complete refresh
  346.                 pBar->mpBarWnd->Show(FALSE);
  347.                 pBar->mpBarWnd->Show(TRUE);
  348.             }
  349.  
  350.             pBar = pBar->mpNext;
  351.         }
  352.  
  353.         while( pRow )
  354.         {
  355.             if ( mCurDragOfs < pRow->mRowY )
  356.             {
  357.                 InsertDraggedRowBefore( pRow );
  358.                 break;
  359.             }
  360.  
  361.             pRow = pRow->mpNext;
  362.         }
  363.  
  364.         if ( pRow == NULL ) InsertDraggedRowBefore( NULL );
  365.  
  366.         mpRowInFocus = NULL;
  367.  
  368.         mpLayout->RecalcLayout(FALSE);
  369.  
  370.         // finish change "transaction"
  371.         mpLayout->GetUpdatesManager().OnFinishChanges();
  372.         mpLayout->GetUpdatesManager().UpdateNow();
  373.  
  374.         // finish drag action
  375.         SetMouseCapture( FALSE );
  376.         mDragStarted = FALSE;
  377.     }
  378. }
  379.  
  380. void cbRowDragPlugin::OnDrawPaneBackground ( cbDrawPaneDecorEvent& event )
  381. {
  382.     mpPane = event.mpPane;
  383.  
  384.     // FIXME:: this may harm operation of other plugins
  385.  
  386.     if ( GetNextHandler() && mpPane->GetRowList().GetCount() )
  387.     {
  388.         // first, let other plugins add their decorations now
  389.     
  390.         GetNextHandler()->ProcessEvent( event );
  391.         event.Skip(FALSE);
  392.     }
  393.  
  394.     wxClientDC dc( &mpLayout->GetParentFrame() );
  395.  
  396.     dc.SetClippingRegion( mpPane->mBoundsInParent.x,
  397.                           mpPane->mBoundsInParent.y,
  398.                           mpPane->mBoundsInParent.width,
  399.                           mpPane->mBoundsInParent.height );
  400.  
  401.     int cnt = GetHRowsCountForPane( event.mpPane );
  402.  
  403.     if ( cnt > 0 ) 
  404.  
  405.         DrawCollapsedRowsBorder( dc );
  406.  
  407.     if ( mpPane->GetRowList().GetCount() )
  408.     
  409.         DrawRowsDragHintsBorder( dc );
  410.  
  411.     cbRowInfo* pRow = GetFirstRow();
  412.  
  413.     while( pRow )
  414.     {
  415.         DrawRowDragHint( pRow, dc, FALSE );
  416.         pRow = pRow->mpNext;
  417.     }
  418.  
  419.     for( int i = 0; i != cnt; ++i )
  420.  
  421.         DrawCollapsedRowIcon(i, dc, FALSE );
  422. }
  423.  
  424. int cbRowDragPlugin::GetHRowsCountForPane( cbDockPane* pPane )
  425. {
  426.     wxNode* pNode = mHiddenBars.First();
  427.  
  428.     int maxIconNo = -1;
  429.  
  430.     while( pNode )
  431.     {
  432.         cbHiddenBarInfo* pHBInfo = (cbHiddenBarInfo*)pNode->Data();
  433.  
  434.         if ( pHBInfo->mAlignment == pPane->mAlignment )
  435.  
  436.             maxIconNo = wxMax( maxIconNo, pHBInfo->mIconNo );
  437.  
  438.         pNode = pNode->Next();
  439.     }
  440.  
  441.     return ( maxIconNo + 1 );
  442. }
  443.  
  444. int cbRowDragPlugin::GetCollapsedRowIconHeight()
  445. {
  446.     return COLLAPSED_ICON_HEIGHT;
  447. }
  448.  
  449. int cbRowDragPlugin::GetRowDragHintWidth()
  450. {
  451.     return ROW_DRAG_HINT_WIDTH;
  452. }
  453.  
  454. void cbRowDragPlugin::SetPaneMargins()
  455. {
  456.     int hiddenRowsCnt = GetHRowsCountForPane( mpPane );
  457.  
  458.     if ( mSvTopMargin == -1 )
  459.     {
  460.         mSvTopMargin    = mpPane->mTopMargin;
  461.         mSvBottomMargin    = mpPane->mBottomMargin;
  462.         mSvLeftMargin   = mpPane->mLeftMargin;
  463.         mSvRightMargin  = mpPane->mRightMargin;
  464.     }
  465.  
  466.     if ( mpPane->IsHorizontal() )
  467.     {
  468.         mpPane->mTopMargin    = mSvTopMargin;
  469.         mpPane->mBottomMargin = ( hiddenRowsCnt == 0 ) 
  470.                                 ?  mSvBottomMargin 
  471.                                 :  mSvBottomMargin + GetCollapsedRowIconHeight();
  472.  
  473.         mpPane->mLeftMargin   = mSvLeftMargin + GetRowDragHintWidth();
  474.         mpPane->mRightMargin  = mSvRightMargin;
  475.     }
  476.     else
  477.     {
  478.         mpPane->mTopMargin    = mSvTopMargin;
  479.         mpPane->mBottomMargin = mSvBottomMargin + GetRowDragHintWidth();
  480.  
  481.         mpPane->mLeftMargin   = mSvLeftMargin;
  482.         mpPane->mRightMargin  = ( hiddenRowsCnt == 0 ) ?
  483.                                 mSvRightMargin : mSvRightMargin + GetCollapsedRowIconHeight();
  484.     }
  485. }
  486.  
  487. void cbRowDragPlugin::OnInitPlugin()
  488. {
  489.     cbDockPane** panes = mpLayout->GetPanesArray();
  490.  
  491.     for( int i = 0; i != MAX_PANES; ++i )
  492.  
  493.         if ( panes[i]->MatchesMask( mPaneMask ) )
  494.         {
  495.             mpPane = panes[i];
  496.  
  497.             SetPaneMargins();
  498.         }
  499. }
  500.  
  501. /*** helpers for drag&drop ***/
  502.  
  503. void cbRowDragPlugin::SetMouseCapture( bool captureOn )
  504. {
  505.     if ( mCaptureIsOn == captureOn ) return;
  506.  
  507.     if ( captureOn ) 
  508.     {
  509.         mpLayout->CaptureEventsForPane( mpPane );
  510.         mpLayout->CaptureEventsForPlugin( this );
  511.     }
  512.     else 
  513.     {
  514.         mpLayout->ReleaseEventsFromPane( mpPane );
  515.         mpLayout->ReleaseEventsFromPlugin( this );
  516.     }
  517.  
  518.     mCaptureIsOn = captureOn;
  519. }
  520.  
  521. void cbRowDragPlugin::UnhighlightItemInFocus()
  522. {
  523.     wxClientDC dc( &mpLayout->GetParentFrame() );
  524.  
  525.     if ( mpRowInFocus ) 
  526.  
  527.         DrawRowDragHint( mpRowInFocus, dc, FALSE );
  528.     else
  529.     if ( mCollapsedIconInFocus != - 1 )
  530.  
  531.         DrawCollapsedRowIcon( mCollapsedIconInFocus, dc, FALSE );
  532. }
  533.  
  534. void cbRowDragPlugin::ShowDraggedRow( int offset )
  535. {
  536.     // create combined image of pane and dragged
  537.     // row on it, in the mpCombinedImage bitmap
  538.  
  539.     if ( mpPane->IsHorizontal() )
  540.     {
  541.         if ( mInitialRowOfs + offset + mRowImgDim.y > mCombRect.y + mCombRect.height )
  542.  
  543.             offset = mCombRect.y + mCombRect.height - mRowImgDim.y - mInitialRowOfs;
  544.  
  545.         if ( mInitialRowOfs + offset < mCombRect.y )
  546.  
  547.             offset = mCombRect.y - mInitialRowOfs;
  548.  
  549.         int x, y = mInitialRowOfs + offset;
  550.         mpPane->FrameToPane( &x, &y );
  551.         mCurDragOfs = y;
  552.     }
  553.     else
  554.     {
  555.         if ( mInitialRowOfs + offset + mRowImgDim.x > mCombRect.x + mCombRect.width )
  556.  
  557.             offset = mCombRect.x + mCombRect.width - mRowImgDim.x - mInitialRowOfs;
  558.  
  559.         if ( mInitialRowOfs + offset < mCombRect.x )
  560.  
  561.             offset = mCombRect.x - mInitialRowOfs;
  562.  
  563.         int x = mInitialRowOfs + offset, y;
  564.         mpPane->FrameToPane( &x, &y );
  565.         mCurDragOfs = x;
  566.     }
  567.  
  568.     wxMemoryDC rowImgDc;
  569.     rowImgDc.SelectObject ( *mpRowImage );
  570.  
  571.     wxMemoryDC paneImgDc;
  572.     paneImgDc.SelectObject( *mpPaneImage );
  573.  
  574.     wxMemoryDC combImgDc;
  575.     combImgDc.SelectObject( *mpCombinedImage );
  576.  
  577.     combImgDc.Blit( 0,0, mCombRect.width, mCombRect.height,
  578.                     &paneImgDc, 0,0, wxCOPY );
  579.  
  580.     if ( mpPane->IsHorizontal() )
  581.     {    
  582.         combImgDc.Blit( 0, mInitialRowOfs + offset - mCombRect.y,
  583.                         mCombRect.width, mRowImgDim.y,
  584.                         &rowImgDc, 0,0, wxCOPY );
  585.     }
  586.     else
  587.     {
  588.         combImgDc.Blit( mInitialRowOfs + offset - mCombRect.x,
  589.                         0,
  590.                         mRowImgDim.x, mCombRect.height,
  591.                         &rowImgDc, 0,0, wxCOPY );
  592.     }
  593.  
  594.     int scrX = mCombRect.x,
  595.         scrY = mCombRect.y;
  596.  
  597.     mpLayout->GetParentFrame().ClientToScreen( &scrX, &scrY );
  598.  
  599.     mpScrDc->Blit( scrX, scrY, mCombRect.width, mCombRect.height,
  600.                    &combImgDc, 0,0, wxCOPY );
  601.  
  602.     rowImgDc .SelectObject( wxNullBitmap );
  603.     paneImgDc.SelectObject( wxNullBitmap );
  604.     combImgDc.SelectObject( wxNullBitmap );
  605. }
  606.  
  607. wxBitmap* cbRowDragPlugin::CaptureDCArea( wxDC& dc, wxRect& area )
  608. {
  609.     wxBitmap* pBmp = new wxBitmap( int(area.width), int(area.height) );
  610.  
  611.     wxMemoryDC mdc;
  612.     mdc.SelectObject( *pBmp );
  613.  
  614.     mdc.Blit( 0,0, area.width, area.height, &dc, area.x, area.y, wxCOPY );
  615.     mdc.SelectObject( wxNullBitmap );
  616.  
  617.     return pBmp;
  618. }
  619.  
  620. void cbRowDragPlugin::PrepareForRowDrag()
  621. {
  622.     wxRect rowBounds = mpRowInFocus->mBoundsInParent;
  623.  
  624.     if ( mpPane->IsHorizontal() )
  625.     {
  626.         mCombRect         = mpPane->mBoundsInParent;
  627.  
  628.         mCombRect.x += mpPane->mLeftMargin - ROW_DRAG_HINT_WIDTH - 1;
  629.         mCombRect.y += mpPane->mTopMargin;
  630.  
  631.         mCombRect.width  -= mpPane->mLeftMargin + mpPane->mRightMargin - ROW_DRAG_HINT_WIDTH - 1 - 1;
  632.         mCombRect.height -= mpPane->mTopMargin  + mpPane->mBottomMargin;
  633.  
  634.         mCombRect.height += 2*rowBounds.height;
  635.         mCombRect.y      -= rowBounds.height;
  636.         mInitialRowOfs     = rowBounds.y;
  637.  
  638.         rowBounds.y      -= 1;
  639.         rowBounds.height += 2;
  640.         rowBounds.x      = mCombRect.x;
  641.         rowBounds.width  = mCombRect.width;
  642.  
  643.         mRowImgDim.y     = rowBounds.height;
  644.     }
  645.     else
  646.     {
  647.         mCombRect = mpPane->mBoundsInParent;
  648.  
  649.         mCombRect.y += mpPane->mTopMargin  - 1; 
  650.         mCombRect.x += mpPane->mLeftMargin - 1;
  651.             ;
  652.         mCombRect.height -= mpPane->mTopMargin  + mpPane->mBottomMargin - ROW_DRAG_HINT_WIDTH - 1 - 1;
  653.         mCombRect.width  -= mpPane->mLeftMargin + mpPane->mRightMargin;
  654.  
  655.         mCombRect.width += 2*rowBounds.width;
  656.         mCombRect.x     -= rowBounds.width;
  657.         mInitialRowOfs    = rowBounds.x;
  658.  
  659.         rowBounds.x      -= 1;
  660.         rowBounds.width  += 2;
  661.         rowBounds.y      = mCombRect.y;
  662.         rowBounds.height = mCombRect.height;
  663.  
  664.         mRowImgDim.x     = rowBounds.width;
  665.     }
  666.     // output cobination results onto frame's client area
  667.     wxScreenDC::StartDrawingOnTop(&mpLayout->GetParentFrame());
  668.     mpScrDc = new wxScreenDC();
  669.  
  670.     int x = mCombRect.x, y = mCombRect.y;
  671.     mpLayout->GetParentFrame().ClientToScreen( &x, &y );
  672.  
  673.     wxRect scrRect = mCombRect;
  674.     scrRect.x = x;
  675.     scrRect.y = y;
  676.  
  677.     mpPaneImage = CaptureDCArea( *mpScrDc, scrRect );
  678.  
  679.     wxMemoryDC mdc;
  680.     mdc.SelectObject( *mpPaneImage );
  681.     mdc.SetDeviceOrigin( -mCombRect.x, -mCombRect.y );
  682.  
  683.     DrawRectShade( rowBounds, mdc, -1, mpLayout->mGrayPen,  mpLayout->mDarkPen  );
  684.     DrawRectShade( rowBounds, mdc, 0, mpLayout->mLightPen, mpLayout->mBlackPen );
  685.  
  686.     mpRowImage = CaptureDCArea( mdc, rowBounds );
  687.  
  688.     // draw dark empty-row placeholder
  689.     DrawEmptyRow( mdc, rowBounds );
  690.  
  691.     //DrawRectShade( rowBounds, mdc, 0, mpLayout->mGrayPen,  mpLayout->mDarkPen  );
  692.     DrawRectShade( rowBounds, mdc, -1, mpLayout->mGrayPen, mpLayout->mGrayPen );
  693.  
  694.     mdc.SelectObject( wxNullBitmap );
  695.  
  696.     mpCombinedImage = new wxBitmap( int(mCombRect.width), int(mCombRect.height) );
  697.  
  698.     // show it for the first time
  699.     ShowDraggedRow( 0 );
  700. }
  701.  
  702. void cbRowDragPlugin::DrawEmptyRow( wxDC& dc, wxRect& rowBounds )
  703. {
  704.     wxBrush bkBrush( mpLayout->mDarkPen.GetColour(), wxSOLID );
  705.  
  706.     // paint the "dark" empty-row placeholder
  707.  
  708.     dc.SetBrush( bkBrush );
  709.     dc.SetPen  ( mpLayout->mNullPen );
  710.  
  711.     dc.DrawRectangle( rowBounds.x, rowBounds.y, 
  712.                       rowBounds.width+1, rowBounds.height+1 );
  713.  
  714.     dc.SetBrush( wxNullBrush );
  715. }
  716.  
  717. void cbRowDragPlugin::ShowPaneImage()
  718. {
  719.     int scrX = 0, scrY = 0;
  720.  
  721.     mpLayout->GetParentFrame().ClientToScreen( &scrX, &scrY );
  722.  
  723.     wxMemoryDC mdc;
  724.     mdc.SelectObject( *mpPaneImage );
  725.  
  726.     mpScrDc->Blit( mCombRect.x + scrX, mCombRect.y + scrY, 
  727.                    mCombRect.width, mCombRect.height,
  728.                    &mdc, 0,0, wxCOPY );
  729.  
  730.     mdc.SelectObject( wxNullBitmap );
  731. }
  732.  
  733. void cbRowDragPlugin::FinishOnScreenDraw()
  734. {
  735.     wxScreenDC::EndDrawingOnTop();
  736.  
  737.     delete mpScrDc;
  738.     delete mpCombinedImage;
  739.     delete mpPaneImage;
  740.     delete mpRowImage;
  741.  
  742.     mpScrDc = NULL;
  743.     
  744.     mpCombinedImage = mpPaneImage = mpRowImage = NULL;
  745. }
  746.  
  747. void cbRowDragPlugin::CollapseRow( cbRowInfo* pRow )
  748. {
  749.     int iconCnt = GetHRowsCountForPane( mpPane );
  750.  
  751.     mpLayout->GetUpdatesManager().OnStartChanges();
  752.  
  753.     cbBarInfo* pBar = pRow->mBars[0];
  754.  
  755.     int rowNo = 0;
  756.  
  757.     cbRowInfo* pCur = pRow;
  758.     while( pCur->mpPrev ) { ++rowNo; pCur = pCur->mpPrev; }
  759.  
  760.     while( pBar )
  761.     {
  762.         cbHiddenBarInfo* pHBInfo = new cbHiddenBarInfo();
  763.                             
  764.         pHBInfo->mpBar      = pBar;
  765.         pHBInfo->mRowNo     = rowNo;
  766.         pHBInfo->mIconNo    = iconCnt;
  767.         pHBInfo->mAlignment    = mpPane->mAlignment;
  768.  
  769.         mHiddenBars.Append( (wxObject*) pHBInfo );
  770.  
  771.         // hide it
  772.         if ( pBar->mpBarWnd )
  773.  
  774.             pBar->mpBarWnd->Show( FALSE );
  775.  
  776.         pBar->mState = wxCBAR_HIDDEN;
  777.  
  778.         cbBarInfo* pNext = pBar->mpNext;
  779.  
  780.         pBar->mpRow  = NULL;
  781.         pBar->mpNext = NULL;
  782.         pBar->mpPrev = NULL;
  783.  
  784.         pBar = pNext;
  785.     }
  786.  
  787.     mpPane->GetRowList().Remove( pRow );
  788.     mpPane->InitLinksForRows();
  789.  
  790.     delete pRow;
  791.  
  792.     SetPaneMargins();
  793.  
  794.     mpLayout->RecalcLayout(FALSE);
  795.  
  796.     mpRowInFocus = NULL;
  797.  
  798.     mpLayout->GetUpdatesManager().OnFinishChanges();
  799.     mpLayout->GetUpdatesManager().UpdateNow();
  800. }
  801.  
  802. void cbRowDragPlugin::ExpandRow( int collapsedIconIdx )
  803. {
  804.     mpLayout->GetUpdatesManager().OnStartChanges();
  805.  
  806.     cbRowInfo* pNewRow = new cbRowInfo();
  807.  
  808.     wxNode* pNode = mHiddenBars.First();
  809.  
  810.     int rowNo = 0;
  811.  
  812.     // move bars from internal list to the newly expanded row 
  813.  
  814.     while( pNode )
  815.     {
  816.         cbHiddenBarInfo* pHBInfo = (cbHiddenBarInfo*)pNode->Data();
  817.  
  818.         if ( pHBInfo->mAlignment     == mpPane->mAlignment &&
  819.              pHBInfo->mIconNo        == collapsedIconIdx   )
  820.         {
  821.             rowNo = pHBInfo->mRowNo;
  822.  
  823.             if ( pHBInfo->mpBar->mState == wxCBAR_HIDDEN )
  824.             {
  825.                 pNewRow->mBars.Add( pHBInfo->mpBar );
  826.  
  827.                 pHBInfo->mpBar->mState = ( mpPane->IsHorizontal() ) 
  828.                                          ? wxCBAR_DOCKED_HORIZONTALLY
  829.                                          : wxCBAR_DOCKED_VERTICALLY;
  830.             }
  831.  
  832.             // remove bar info from internal list
  833.  
  834.             wxNode* pNext = pNode->Next();
  835.  
  836.             delete pHBInfo;
  837.             mHiddenBars.DeleteNode( pNode );
  838.  
  839.             pNode = pNext;
  840.         }
  841.         else
  842.         {
  843.             // decrease incon numbers with higher indicies, since this
  844.             // row is now removed from the hidden-rows list
  845.  
  846.             if ( pHBInfo->mIconNo    > collapsedIconIdx &&
  847.                  pHBInfo->mAlignment == mpPane->mAlignment )
  848.  
  849.                 --pHBInfo->mIconNo;
  850.  
  851.             pNode = pNode->Next();
  852.         }
  853.     }
  854.  
  855.     mpPane->InitLinksForRow( pNewRow );
  856.  
  857.     // insert row into pane at it's original position
  858.  
  859.     if ( pNewRow->mBars.GetCount() )
  860.     {
  861.         cbRowInfo* beforeRowNode = mpPane->GetRow( rowNo );
  862.  
  863.         mpPane->InsertRow( pNewRow, beforeRowNode );
  864.     }
  865.     else
  866.         delete pNewRow;
  867.  
  868.     SetPaneMargins();
  869.  
  870.     mpLayout->RecalcLayout(FALSE);
  871.  
  872.     mCollapsedIconInFocus = -1;
  873.  
  874.     mpLayout->GetUpdatesManager().OnFinishChanges();
  875.     mpLayout->GetUpdatesManager().UpdateNow();
  876.  
  877.  
  878.     /*
  879.     wxNode* pRowNode = mHiddenRows.Nth( collapsedIconIdx );
  880.  
  881.     mpLayout->GetUpdatesManager().OnStartChanges();
  882.  
  883.     // insert at the end of rows list
  884.     mpPane->InsertRow( pRowNode, NULL );
  885.  
  886.     int success = mHiddenRows.DeleteNode( pRowNode );
  887.     // DBG::
  888.     wxASSERT( success );
  889.  
  890.     SetPaneMargins();
  891.  
  892.     mpLayout->RecalcLayout(FALSE);
  893.  
  894.     mCollapsedIconInFocus = -1;
  895.  
  896.     mpLayout->GetUpdatesManager().OnFinishChanges();
  897.     mpLayout->GetUpdatesManager().UpdateNow();
  898.     */
  899. }
  900.  
  901. void cbRowDragPlugin::InsertDraggedRowBefore( cbRowInfo* pBeforeRow )
  902. {
  903.     if ( mpRowInFocus != pBeforeRow &&
  904.          mpRowInFocus->mpNext != pBeforeRow 
  905.        )
  906.     {
  907.         mpPane->GetRowList().Remove( mpRowInFocus );
  908.  
  909.         mpPane->InsertRow( mpRowInFocus, pBeforeRow );
  910.     }
  911.     else 
  912.     {
  913.         // otherwise, nothing has happned (row positions do not change)
  914.  
  915.         //wxClientDC dc( &mpLayout->GetParentFrame() );
  916.  
  917.         //mpPane->PaintRow( mpRowInFocus, dc );
  918.         //DrawRowDragHint( mpRowInFocus, dc, FALSE );
  919.     }
  920. }
  921.  
  922. bool cbRowDragPlugin::ItemIsInFocus()
  923. {
  924.     return ( mpRowInFocus || mCollapsedIconInFocus != - 1 );
  925. }
  926.  
  927. void cbRowDragPlugin::CheckPrevItemInFocus( cbRowInfo* pRow, int iconIdx )
  928. {
  929.     wxClientDC dc( &mpLayout->GetParentFrame() );
  930.  
  931.     if ( pRow != NULL && mpRowInFocus == pRow ) return;
  932.     if ( iconIdx != -1 && mCollapsedIconInFocus == iconIdx ) return;
  933.  
  934.     UnhighlightItemInFocus();
  935.  
  936.     if ( iconIdx != - 1 )
  937.     
  938.         DrawCollapsedRowIcon( iconIdx, dc, TRUE );
  939.  
  940.     else
  941.     if ( pRow != NULL )
  942.  
  943.         DrawRowDragHint( pRow, dc, TRUE );
  944. }
  945.  
  946. cbRowInfo* cbRowDragPlugin::GetFirstRow()
  947. {
  948.     return ( mpPane->GetRowList().GetCount() ) 
  949.            ? mpPane->GetRowList()[0]
  950.            : NULL;
  951. }
  952.  
  953. /*** "hard-coded" metafile for NN-look ***/
  954.  
  955. void cbRowDragPlugin::DrawTrianUp( wxRect& inRect, wxDC& dc )
  956. {
  957.     int xOfs = (inRect.width - ICON_TRIAN_WIDTH)/2;
  958.  
  959.     wxBrush br( mTrianInnerColor, wxSOLID );
  960.  
  961.     dc.SetBrush( br );
  962.     dc.SetPen( mpLayout->mBlackPen );
  963.  
  964.     wxPoint points[3];
  965.     points[0].x = inRect.x + xOfs;
  966.     points[0].y = inRect.y + inRect.height - 1;
  967.     points[1].x = inRect.x + xOfs + ICON_TRIAN_WIDTH/2 + 1;
  968.     points[1].y = inRect.y + inRect.height - 2 - ICON_TRIAN_HEIGHT;
  969.     points[2].x = inRect.x + xOfs + ICON_TRIAN_WIDTH+1;
  970.     points[2].y = inRect.y + inRect.height - 1;
  971.  
  972.     dc.DrawPolygon( 3, points );
  973.  
  974.     // higlight upper-right edge of triangle
  975.     dc.SetPen( mpLayout->mLightPen );
  976.     dc.DrawLine( points[2].x, points[2].y,
  977.                  points[0].x, points[0].y );
  978.  
  979.     dc.SetBrush( wxNullBrush );
  980. }
  981.  
  982. void cbRowDragPlugin::DrawTrianDown( wxRect& inRect, wxDC& dc )
  983. {
  984.     int xOfs = (inRect.width - ICON_TRIAN_WIDTH)/2;
  985.  
  986.     wxBrush br( mTrianInnerColor, wxSOLID );
  987.  
  988.     dc.SetBrush( br );
  989.     dc.SetPen( mpLayout->mBlackPen );
  990.  
  991.     wxPoint points[3];
  992.     points[0].x = inRect.x + xOfs;
  993.     points[0].y = inRect.y;
  994.     points[1].x = inRect.x + xOfs + ICON_TRIAN_WIDTH;
  995.     points[1].y = inRect.y;
  996.     points[2].x = inRect.x + xOfs + ICON_TRIAN_WIDTH/2;
  997.     points[2].y = inRect.y + ICON_TRIAN_HEIGHT;
  998.  
  999.     dc.DrawPolygon( 3, points );
  1000.  
  1001.     // higlight upper-right edge of triangle
  1002.     dc.SetPen( mpLayout->mLightPen );
  1003.     dc.DrawLine( points[2].x, points[2].y,
  1004.                  points[1].x, points[1].y );
  1005.  
  1006.     dc.SetBrush( wxNullBrush );
  1007. }
  1008.  
  1009. void cbRowDragPlugin::DrawTrianRight( wxRect& inRect, wxDC& dc )
  1010. {
  1011.     int yOfs = (inRect.height - ICON_TRIAN_WIDTH)/2;
  1012.  
  1013.     wxBrush br( mTrianInnerColor, wxSOLID );
  1014.  
  1015.     dc.SetBrush( br );
  1016.     dc.SetPen( mpLayout->mBlackPen );
  1017.  
  1018.     wxPoint points[3];
  1019.     points[0].x = inRect.x;
  1020.     points[0].y = inRect.y + yOfs + ICON_TRIAN_WIDTH;
  1021.     points[1].x = inRect.x;
  1022.     points[1].y = inRect.y + yOfs;
  1023.     points[2].x = inRect.x + ICON_TRIAN_HEIGHT;
  1024.     points[2].y = inRect.y + yOfs + ICON_TRIAN_WIDTH/2;
  1025.  
  1026.     dc.DrawPolygon( 3, points );
  1027.  
  1028.     // higlight upper-right edge of triangle
  1029.     dc.SetPen( mpLayout->mLightPen );
  1030.     dc.DrawLine( points[0].x, points[0].y,
  1031.                  points[2].x, points[2].y );
  1032.  
  1033.     dc.SetBrush( wxNullBrush );
  1034. }
  1035.  
  1036. void cbRowDragPlugin::Draw3DPattern( wxRect& inRect, wxDC& dc )
  1037. {
  1038.     for( int y = inRect.y; y < inRect.y + inRect.height; y+=3 )
  1039.     
  1040.         for( int x = inRect.x; x < inRect.x + inRect.width; x+=3 )
  1041.         {
  1042.             dc.SetPen( mpLayout->mLightPen );
  1043.             dc.DrawPoint( x,y );
  1044.             dc.SetPen( mpLayout->mBlackPen );
  1045.             dc.DrawPoint( x+1, y+1 );
  1046.         }
  1047. }
  1048.  
  1049. void cbRowDragPlugin::DrawRombShades( wxPoint& p1, wxPoint& p2, 
  1050.                                       wxPoint& p3, wxPoint& p4,
  1051.                                       wxDC& dc )
  1052. {
  1053.     dc.SetPen( mpLayout->mLightPen );
  1054.     dc.DrawLine( p1.x, p1.y, p2.x, p2.y );
  1055.     dc.DrawLine( p2.x, p2.y, p3.x, p3.y );
  1056.     dc.SetPen( mpLayout->mDarkPen );
  1057.     dc.DrawLine( p3.x, p3.y, p4.x, p4.y );
  1058.     dc.DrawLine( p4.x, p4.y, p1.x, p1.y );
  1059. }
  1060.  
  1061. void cbRowDragPlugin::DrawOrtoRomb( wxRect& inRect, wxDC& dc, wxBrush& bkBrush )
  1062. {
  1063.     dc.SetBrush( bkBrush );
  1064.     dc.SetPen( mpLayout->mBlackPen );
  1065.  
  1066.     wxPoint points[4];
  1067.  
  1068.     if ( inRect.width > inRect.height )
  1069.     {
  1070.         // horizontal orienation
  1071.         points[0].x = inRect.x;
  1072.         points[0].y = inRect.y + inRect.height;
  1073.         points[1].x = inRect.x;
  1074.         points[1].y = inRect.y;
  1075.         points[2].x = inRect.x + inRect.width;
  1076.         points[2].y = inRect.y;
  1077.         points[3].x = inRect.x + inRect.width - COLLAPSED_ICON_HEIGHT;
  1078.         points[3].y = inRect.y + inRect.height;
  1079.  
  1080.         dc.DrawPolygon( 4, points );
  1081.  
  1082.         // squeeze romb's bounds to create an inner-shade shape
  1083.         ++points[0].x;
  1084.         --points[0].y;
  1085.         ++points[1].x;
  1086.         ++points[1].y;
  1087.         --points[2].x; --points[2].x;
  1088.         ++points[2].y;
  1089.         --points[3].y;
  1090.  
  1091.         DrawRombShades( points[0], points[1], points[2], points[3], dc );
  1092.     }
  1093.     else
  1094.     {
  1095.         // vertical orientation
  1096.         points[0].x = inRect.x + inRect.width;
  1097.         points[0].y = inRect.y + inRect.height;
  1098.         points[1].x = inRect.x;
  1099.         points[1].y = inRect.y + inRect.height;
  1100.         points[2].x = inRect.x;
  1101.         points[2].y = inRect.y;
  1102.         points[3].x = inRect.x + inRect.width;
  1103.         points[3].y = inRect.y + COLLAPSED_ICON_HEIGHT;
  1104.  
  1105.         dc.DrawPolygon( 4, points );
  1106.  
  1107.         // squeeze romb's bounds to create an inner-shade shape
  1108.         --points[0].y ;
  1109.         --points[0].x;
  1110.         ++points[1].x;
  1111.         --points[1].y;
  1112.         ++points[2].y; ++points[2].y;
  1113.         ++points[2].x;
  1114.         --points[3].x;
  1115.  
  1116.         DrawRombShades( points[1], points[2], points[3], points[0], dc );
  1117.     }
  1118.  
  1119.     dc.SetBrush( wxNullBrush );
  1120. }
  1121.  
  1122. void cbRowDragPlugin::DrawRomb( wxRect& inRect, wxDC& dc, wxBrush& bkBrush )
  1123. {
  1124.     wxPoint points[4];
  1125.  
  1126.     dc.SetBrush( bkBrush );
  1127.     dc.SetPen( mpLayout->mBlackPen );
  1128.  
  1129.     if ( inRect.width > inRect.height )
  1130.     {
  1131.         // horizontal orientation
  1132.         points[0].x = inRect.x;
  1133.         points[0].y = inRect.y + inRect.height;
  1134.         points[1].x = inRect.x + COLLAPSED_ICON_HEIGHT;
  1135.         points[1].y = inRect.y;
  1136.         points[2].x = inRect.x + inRect.width;
  1137.         points[2].y = inRect.y;
  1138.         points[3].x = inRect.x + inRect.width - COLLAPSED_ICON_HEIGHT;
  1139.         points[3].y = inRect.y + inRect.height;
  1140.  
  1141.         dc.DrawPolygon( 4, points );
  1142.  
  1143.         // squeeze romb's bounds to create an inner-shade shape
  1144.         ++points[0].x ;++points[0].x ;
  1145.         --points[0].y;
  1146.         ++points[1].y;
  1147.         --points[2].x; --points[2].x;
  1148.         ++points[2].y;
  1149.         //--points[3].x ;
  1150.         --points[3].y;
  1151.  
  1152.         DrawRombShades( points[0], points[1], points[2], points[3], dc );
  1153.  
  1154.     }
  1155.     else
  1156.     {
  1157.         // vertical orientation
  1158.         points[0].x = inRect.x + inRect.width;
  1159.         points[0].y = inRect.y + inRect.height;
  1160.         points[1].x = inRect.x;
  1161.         points[1].y = inRect.y + inRect.height - COLLAPSED_ICON_HEIGHT;
  1162.         points[2].x = inRect.x;
  1163.         points[2].y = inRect.y;
  1164.         points[3].x = inRect.x + inRect.width;
  1165.         points[3].y = inRect.y + COLLAPSED_ICON_HEIGHT;
  1166.  
  1167.         dc.DrawPolygon( 4, points );
  1168.  
  1169.         // squeeze romb's bounds to create an inner-shade shape
  1170.         --points[0].y ;--points[0].y ;
  1171.         --points[0].x;
  1172.         ++points[1].x;
  1173.         ++points[2].y; ++points[2].y;
  1174.         ++points[2].x;
  1175.         --points[3].x;
  1176.  
  1177.         DrawRombShades( points[1], points[2], points[3], points[0], dc );
  1178.     }
  1179.  
  1180.     dc.SetBrush( wxNullBrush );
  1181. }
  1182.  
  1183. void cbRowDragPlugin::DrawRectShade( wxRect& inRect, wxDC& dc, 
  1184.                                      int level, wxPen& upperPen, wxPen& lowerPen )
  1185. {
  1186.     // upper shade
  1187.     dc.SetPen( upperPen );
  1188.     dc.DrawLine( inRect.x - level, 
  1189.                  inRect.y - level, 
  1190.                  inRect.x + inRect.width - 1 + level, 
  1191.                  inRect.y - level);
  1192.     dc.DrawLine( inRect.x - level, inRect.y - level,
  1193.                  inRect.x - level, inRect.y + inRect.height - 1 + level );
  1194.  
  1195.     // lower shade
  1196.     dc.SetPen( lowerPen );
  1197.     dc.DrawLine( inRect.x - level, 
  1198.                  inRect.y + inRect.height - 1 + level,
  1199.                  inRect.x + inRect.width  + level,
  1200.                  inRect.y + inRect.height - 1 + level);
  1201.     dc.DrawLine( inRect.x + inRect.width - 1 + level,
  1202.                  inRect.y - level,
  1203.                  inRect.x + inRect.width - 1 + level,
  1204.                  inRect.y + inRect.height + level);
  1205.  
  1206.     dc.SetBrush( wxNullBrush );
  1207. }
  1208.  
  1209. void cbRowDragPlugin::Draw3DRect( wxRect& inRect, wxDC& dc, wxBrush& bkBrush )
  1210. {
  1211.     dc.SetPen( mpLayout->mNullPen );
  1212.     dc.SetBrush( bkBrush );
  1213.  
  1214.     dc.DrawRectangle( inRect.x, inRect.y,
  1215.                       inRect.width, inRect.height );
  1216.  
  1217.     DrawRectShade( inRect, dc, 0, mpLayout->mLightPen, mpLayout->mDarkPen );
  1218. }
  1219.  
  1220. int  cbRowDragPlugin::GetCollapsedIconsPos()
  1221. {
  1222.     RowArrayT& rows = mpPane->GetRowList();
  1223.  
  1224.     if ( rows.GetCount() == 0 ) 
  1225.     {
  1226.         if ( mpPane->IsHorizontal() )
  1227.             
  1228.             return mpPane->mBoundsInParent.y + mpPane->mTopMargin;
  1229.         else
  1230.             return mpPane->mBoundsInParent.x + mpPane->mLeftMargin;
  1231.     }
  1232.  
  1233.     wxRect& bounds = rows[ rows.GetCount() - 1 ]->mBoundsInParent;
  1234.  
  1235.     if ( mpPane->IsHorizontal() )
  1236.  
  1237.         return bounds.y + bounds.height + 1;
  1238.     else
  1239.         return bounds.x + bounds.width  + 1;
  1240.  
  1241. }
  1242.  
  1243. void cbRowDragPlugin::GetRowHintRect( cbRowInfo* pRow, wxRect& rect )
  1244. {
  1245.     wxRect& bounds = pRow->mBoundsInParent;
  1246.  
  1247.     if ( mpPane->IsHorizontal() )
  1248.     {
  1249.         rect.x = bounds.x - ROW_DRAG_HINT_WIDTH - 1;
  1250.         rect.y = bounds.y;
  1251.         rect.width = ROW_DRAG_HINT_WIDTH;
  1252.         rect.height = bounds.height;
  1253.     }
  1254.     else
  1255.     {
  1256.         rect.x = bounds.x;
  1257.         rect.y = bounds.y + bounds.height + 1;
  1258.         rect.width = bounds.width;
  1259.         rect.height = ROW_DRAG_HINT_WIDTH;
  1260.     }
  1261. }
  1262.  
  1263. void cbRowDragPlugin::GetCollapsedInconRect( int iconIdx, wxRect& rect )
  1264. {
  1265.     int upper = GetCollapsedIconsPos();
  1266.  
  1267.     int right = (iconIdx == 0 ) 
  1268.                 ? 0 : iconIdx * (COLLAPSED_ICON_WIDTH - COLLAPSED_ICON_HEIGHT);
  1269.  
  1270.     if ( mpPane->IsHorizontal() )
  1271.     {
  1272.         rect.x = mpPane->mBoundsInParent.x + mpPane->mLeftMargin - ROW_DRAG_HINT_WIDTH - 1
  1273.                  + right;
  1274.  
  1275.         rect.y = upper;
  1276.         rect.width  = COLLAPSED_ICON_WIDTH;
  1277.         rect.height = COLLAPSED_ICON_HEIGHT;
  1278.     }
  1279.     else
  1280.     {
  1281.          rect.x = upper;
  1282.          rect.y = mpPane->mBoundsInParent.y + mpPane->mBoundsInParent.height 
  1283.                  - mpPane->mBottomMargin + ROW_DRAG_HINT_WIDTH + 1
  1284.                  - right - COLLAPSED_ICON_WIDTH;
  1285.  
  1286.         rect.height = COLLAPSED_ICON_WIDTH;
  1287.         rect.width  = COLLAPSED_ICON_HEIGHT;
  1288.     }
  1289. }
  1290.  
  1291. /*** overridables ***/
  1292.  
  1293. void cbRowDragPlugin::DrawCollapsedRowIcon( int index, wxDC& dc, bool isHighlighted )
  1294. {
  1295.     wxRect rect;
  1296.     GetCollapsedInconRect( index, rect );
  1297.  
  1298.     wxBrush  hiBrush ( mHightColor, wxSOLID );
  1299.     wxBrush  lowBrush( mLowColor,   wxSOLID );
  1300.     wxBrush& curBrush = ( isHighlighted ) ? hiBrush : lowBrush;
  1301.  
  1302.     if ( mpPane->IsHorizontal() )
  1303.     {                 
  1304.         if ( index == 0 )
  1305.  
  1306.             DrawOrtoRomb( rect, dc, curBrush );
  1307.         else
  1308.             DrawRomb( rect, dc, curBrush );
  1309.  
  1310.         int triOfs = (index == 0) ? TRIANGLE_OFFSET : TRIANGLE_OFFSET + COLLAPSED_ICON_HEIGHT;
  1311.  
  1312.         wxRect triRect;
  1313.         triRect.x = triOfs + rect.x;
  1314.  
  1315.         triRect.width = ICON_TRIAN_HEIGHT;
  1316.         triRect.y = rect.y;
  1317.         triRect.height = rect.height;
  1318.  
  1319.         DrawTrianRight( triRect, dc );
  1320.  
  1321.         wxRect patRect;
  1322.         patRect.x      = triOfs + ICON_TRIAN_HEIGHT + TRIANGLE_TO_PAT_GAP + rect.x;
  1323.         patRect.y      = rect.y + PAT_OFFSET; 
  1324.         patRect.width  = rect.width - (patRect.x - rect.x) - COLLAPSED_ICON_HEIGHT - PAT_OFFSET;
  1325.         patRect.height = rect.height - PAT_OFFSET*2;
  1326.  
  1327.         Draw3DPattern( patRect, dc );
  1328.     }
  1329.     else
  1330.     {
  1331.         if ( index == 0 )
  1332.  
  1333.             DrawOrtoRomb( rect, dc, curBrush );
  1334.         else
  1335.             DrawRomb( rect, dc, curBrush );
  1336.  
  1337.         int triOfs = (index == 0) 
  1338.                      ? TRIANGLE_OFFSET + ICON_TRIAN_HEIGHT
  1339.                      : TRIANGLE_OFFSET + COLLAPSED_ICON_HEIGHT + ICON_TRIAN_HEIGHT;
  1340.  
  1341.         wxRect triRect;
  1342.         triRect.y      = rect.y + rect.height - triOfs;
  1343.         triRect.x      = rect.x;
  1344.         triRect.width  = rect.width;
  1345.         triRect.height = ICON_TRIAN_HEIGHT;
  1346.  
  1347.         DrawTrianUp( triRect, dc );
  1348.  
  1349.         wxRect patRect;
  1350.         patRect.y      = rect.y + COLLAPSED_ICON_HEIGHT + PAT_OFFSET;
  1351.         patRect.x      = rect.x + PAT_OFFSET; 
  1352.         patRect.width  = rect.width - 2*PAT_OFFSET ;
  1353.         patRect.height = rect.height - triOfs - 2*PAT_OFFSET - COLLAPSED_ICON_HEIGHT;
  1354.  
  1355.         Draw3DPattern( patRect, dc );
  1356.     }
  1357. }
  1358.  
  1359. void cbRowDragPlugin::DrawRowDragHint( cbRowInfo* pRow , wxDC& dc, bool isHighlighted )
  1360. {
  1361.     wxRect rect;
  1362.     GetRowHintRect( pRow, rect );
  1363.  
  1364.     wxBrush  hiBrush ( mHightColor, wxSOLID );
  1365.     wxBrush  lowBrush( mLowColor,   wxSOLID );
  1366.     wxBrush& curBrush = ( isHighlighted ) ? hiBrush : lowBrush;
  1367.  
  1368.     Draw3DRect( rect, dc, curBrush );
  1369.  
  1370.     if ( mpPane->IsHorizontal() )
  1371.     {
  1372.         wxRect triRect;
  1373.         triRect.y       = rect.y + TRIANGLE_OFFSET;
  1374.         triRect.x       = rect.x;
  1375.         triRect.width  = rect.width;
  1376.         triRect.height = ICON_TRIAN_HEIGHT;
  1377.  
  1378.         DrawTrianDown( triRect, dc );
  1379.  
  1380.         wxRect patRect;
  1381.         patRect.x      = rect.x + PAT_OFFSET;
  1382.         patRect.y      = rect.y + TRIANGLE_OFFSET + ICON_TRIAN_HEIGHT + TRIANGLE_TO_PAT_GAP;
  1383.         patRect.width  = rect.width - 2*PAT_OFFSET;
  1384.         patRect.height = rect.height - ( patRect.y - rect.y ) - PAT_OFFSET;
  1385.         Draw3DPattern( patRect, dc );
  1386.  
  1387.         dc.SetPen( mpLayout->mLightPen );
  1388.         dc.DrawLine( rect.x, rect.y + rect.height, rect.x + rect.width, rect.y + rect.height );
  1389.     }
  1390.     else
  1391.     {
  1392.         wxRect triRect;
  1393.         triRect.x       = rect.x + TRIANGLE_OFFSET;
  1394.         triRect.y       = rect.y;
  1395.         triRect.height = rect.height;
  1396.         triRect.width  = ICON_TRIAN_HEIGHT;
  1397.  
  1398.         DrawTrianRight( triRect, dc );
  1399.  
  1400.         wxRect patRect;
  1401.         patRect.y      = rect.y + PAT_OFFSET;
  1402.         patRect.x      = rect.x + TRIANGLE_OFFSET + ICON_TRIAN_HEIGHT + TRIANGLE_TO_PAT_GAP;
  1403.         patRect.height = rect.height - 2*PAT_OFFSET;
  1404.         patRect.width  = rect.width - ( patRect.x - rect.x ) - PAT_OFFSET;
  1405.         Draw3DPattern( patRect, dc );
  1406.  
  1407.         dc.SetPen( mpLayout->mLightPen );
  1408.         dc.DrawLine( rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + rect.height );
  1409.     }
  1410. }
  1411.  
  1412. void cbRowDragPlugin::DrawRowsDragHintsBorder( wxDC& dc )
  1413. {
  1414.     // FIXME:: what was that?
  1415. }
  1416.  
  1417. void cbRowDragPlugin::DrawCollapsedRowsBorder( wxDC& dc )
  1418. {
  1419.     int colRowOfs = GetCollapsedIconsPos();
  1420.     wxRect& bounds = mpPane->mBoundsInParent;
  1421.  
  1422.     wxBrush bkBrush( mpLayout->mGrayPen.GetColour(), wxSOLID );
  1423.     dc.SetBrush( bkBrush );
  1424.     dc.SetPen( mpLayout->mDarkPen );
  1425.  
  1426.     if ( mpPane->IsHorizontal() )
  1427.     
  1428.         dc.DrawRectangle( bounds.x + mpPane->mLeftMargin - ROW_DRAG_HINT_WIDTH - 1,
  1429.                           colRowOfs,
  1430.                           bounds.width - mpPane->mLeftMargin - mpPane->mRightMargin + 2 + ROW_DRAG_HINT_WIDTH,
  1431.                           COLLAPSED_ICON_HEIGHT + 1);
  1432.     else
  1433.         dc.DrawRectangle( colRowOfs,
  1434.                           bounds.y + mpPane->mTopMargin - 1,
  1435.                           COLLAPSED_ICON_HEIGHT + 1,
  1436.                           bounds.height - mpPane->mTopMargin - mpPane->mBottomMargin 
  1437.                           - ROW_DRAG_HINT_WIDTH - 2 );
  1438.  
  1439.     dc.SetBrush( wxNullBrush );
  1440. }
  1441.  
  1442. static inline bool rect_contains_point( const wxRect& rect, int x, int y )
  1443. {
  1444.     return ( x >= rect.x &&
  1445.              y >= rect.y &&
  1446.              x <  rect.x + rect.width  &&
  1447.              y <  rect.y + rect.height );
  1448. }
  1449.  
  1450. bool cbRowDragPlugin::HitTestCollapsedRowIcon( int iconIdx, const wxPoint& pos )
  1451. {
  1452.     wxRect bounds;
  1453.     GetCollapsedInconRect( iconIdx, bounds );
  1454.  
  1455.     return rect_contains_point( bounds, pos.x, pos.y );
  1456. }
  1457.  
  1458. bool cbRowDragPlugin::HitTestRowDragHint( cbRowInfo* pRow, const wxPoint& pos )
  1459. {
  1460.     wxRect bounds;
  1461.     GetRowHintRect( pRow, bounds );
  1462.  
  1463.     return rect_contains_point( bounds, pos.x, pos.y );
  1464. }
  1465.  
  1466.