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 / panedrawpl.cpp < prev    next >
C/C++ Source or Header  |  2002-04-04  |  39KB  |  1,285 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        panedrawpl.cpp
  3. // Purpose:     cbPaneDrawPlugin implementation.
  4. // Author:      Aleksandras Gluchovas
  5. // Modified by:
  6. // Created:     06/09/98
  7. // RCS-ID:      $Id: panedrawpl.cpp,v 1.4 2002/04/04 21:05:14 JS Exp $
  8. // Copyright:   (c) Aleksandras Gluchovas
  9. // Licence:       wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. #ifdef __GNUG__
  13.     #pragma implementation "panedrawpl.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 <math.h>
  28. #include <stdlib.h>
  29.  
  30. #include "wx/utils.h"     // import wxMin,wxMax macros
  31.  
  32. #include "wx/fl/panedrawpl.h"
  33.  
  34. // bitmap bits used by bar-resizing brush
  35.  
  36. #define _IMG_A  0xAA    // Note: modified from _A to _IMG_A, _A was already defined (cygwin)
  37. #define _IMG_B  0x00    // Note: modified from _B to _IMG_A, _B was already defined (cygwin)
  38. #define _IMG_C  0x55    // Note: modified from _C to _IMG_C, for consistency reasons.
  39. #define _IMG_D  0x00    // Note: modified from _D to _IMG_D, for consistency reasons.
  40.  
  41. static const unsigned char _gCheckerImg[16] = { _IMG_A,_IMG_B,_IMG_C,_IMG_D,
  42.                                                 _IMG_A,_IMG_B,_IMG_C,_IMG_D,
  43.                                                 _IMG_A,_IMG_B,_IMG_C,_IMG_D,
  44.                                                 _IMG_A,_IMG_B,_IMG_C,_IMG_D
  45.                                               };
  46.  
  47. // FIXME:: The below code somehow doesn't work - cursors remain unchanged
  48. // Used: controlbar.cpp(1268):    set_cursor_bits( _gHorizCursorImg, bits, 32, 16 );
  49. // Used: controlbar.cpp(1272):    set_cursor_bits( _gVertCursorImg, bits, 32, 16 );
  50. /*
  51. static void set_cursor_bits( const char** img, char* bits, int width, int height )
  52. {
  53.     for( int i = 0; i != (width*height)/8; ++i )
  54.         bits[i] = 0;
  55.  
  56.     for( int y = 0; y != height; ++y )
  57.     {
  58.         const char* row = img[0];
  59.  
  60.         for( int x = 0; x != width; ++x )
  61.         {
  62.             int bitNo = y*width + x;
  63.  
  64.             char value = ( row[x] != '.' ) ? 1 : 0;
  65.  
  66.             bits[ bitNo / sizeof(char) ] |= 
  67.                 ( ( bitNo %sizeof(char) ) << value );
  68.         }
  69.  
  70.         ++img;
  71.     }
  72. }
  73. */
  74.  
  75. /***** Implementation for class cbPaneDrawPlugin *****/
  76.  
  77. IMPLEMENT_DYNAMIC_CLASS( cbPaneDrawPlugin, cbPluginBase )
  78.  
  79. BEGIN_EVENT_TABLE( cbPaneDrawPlugin, cbPluginBase )
  80.  
  81.     EVT_PL_LEFT_DOWN           ( cbPaneDrawPlugin::OnLButtonDown         )
  82.     EVT_PL_LEFT_UP               ( cbPaneDrawPlugin::OnLButtonUp           )
  83. //    EVT_PL_LEFT_DCLICK           ( cbPaneDrawPlugin::OnLDblClick           )
  84.     EVT_PL_RIGHT_UP               ( cbPaneDrawPlugin::OnRButtonUp           )
  85.     EVT_PL_MOTION               ( cbPaneDrawPlugin::OnMouseMove           )
  86.  
  87.  
  88.     EVT_PL_DRAW_PANE_BKGROUND  ( cbPaneDrawPlugin::OnDrawPaneBackground  )
  89.     EVT_PL_DRAW_PANE_DECOR     ( cbPaneDrawPlugin::OnDrawPaneDecorations )
  90.  
  91.     EVT_PL_DRAW_ROW_DECOR      ( cbPaneDrawPlugin::OnDrawRowDecorations  )
  92.     EVT_PL_DRAW_ROW_HANDLES    ( cbPaneDrawPlugin::OnDrawRowHandles      )
  93.     EVT_PL_DRAW_ROW_BKGROUND   ( cbPaneDrawPlugin::OnDrawRowBackground   )
  94.  
  95.     EVT_PL_SIZE_BAR_WND           ( cbPaneDrawPlugin::OnSizeBarWindow       )
  96.     EVT_PL_DRAW_BAR_DECOR       ( cbPaneDrawPlugin::OnDrawBarDecorations  )
  97.     EVT_PL_DRAW_BAR_HANDLES       ( cbPaneDrawPlugin::OnDrawBarHandles      )
  98.  
  99.     EVT_PL_START_DRAW_IN_AREA  ( cbPaneDrawPlugin::OnStartDrawInArea     )
  100.     EVT_PL_FINISH_DRAW_IN_AREA ( cbPaneDrawPlugin::OnFinishDrawInArea    )
  101.  
  102. END_EVENT_TABLE()
  103.  
  104. cbPaneDrawPlugin::cbPaneDrawPlugin(void)
  105.  
  106.     : mResizeStarted          ( FALSE ),
  107.  
  108.       mResizeCursorOn         ( FALSE ),
  109.       mpDraggedBar              ( NULL  ),
  110.       mpResizedRow            ( NULL  ),
  111.  
  112.       mRowHandleHitted        ( FALSE ),
  113.       mIsUpperHandle          ( FALSE ),
  114.       mBarHandleHitted        ( FALSE ),
  115.       mIsLeftHandle           ( FALSE ),
  116.       mBarContentHitted       ( FALSE ),
  117.  
  118.       mpClntDc ( NULL ),
  119.       mpPane   ( NULL )
  120. {}
  121.  
  122. cbPaneDrawPlugin::cbPaneDrawPlugin( wxFrameLayout* pPanel, int paneMask )
  123.  
  124.     : cbPluginBase( pPanel, paneMask ),
  125.     
  126.       // bar-row resizing state varaibles
  127.  
  128.       mResizeStarted          ( FALSE ),
  129.  
  130.       mResizeCursorOn         ( FALSE ),
  131.       mpDraggedBar              ( NULL ),
  132.       mpResizedRow            ( NULL ),
  133.  
  134.       mRowHandleHitted        ( FALSE ),
  135.       mIsUpperHandle          ( FALSE ),
  136.       mBarHandleHitted        ( FALSE ),
  137.       mIsLeftHandle           ( FALSE ),
  138.       mBarContentHitted       ( FALSE ),
  139.  
  140.       mpClntDc ( NULL ),
  141.       mpPane   ( NULL )
  142. {}
  143.  
  144. cbPaneDrawPlugin::~cbPaneDrawPlugin()
  145. {
  146.     // DBG::
  147.     wxASSERT( mpClntDc == NULL );
  148. }
  149.  
  150. void cbPaneDrawPlugin::DrawDraggedHandle( const wxPoint& pos, cbDockPane& pane )
  151. {
  152.     wxScreenDC dc;
  153.     int ofsX = 0;
  154.     int ofsY = 0;
  155.  
  156.     wxPoint fpos = pos;
  157.     pane.PaneToFrame( &fpos.x, &fpos.y );
  158.  
  159.     // short-cut
  160.     int resizeHndSize = pane.mProps.mResizeHandleSize;
  161.  
  162.     // "Required for X to specify that
  163.     // that we wish to draw on top of all windows
  164.     // - and we optimise by specifying the area
  165.     // for creating the overlap window." --J.S.
  166.  
  167.     wxScreenDC::StartDrawingOnTop(&mpLayout->GetParentFrame());
  168.  
  169.     mpLayout->GetParentFrame().ClientToScreen( &ofsX, &ofsY );
  170.  
  171.     int prevLF = dc.GetLogicalFunction();
  172.  
  173.     // BUG BUG BUG (wx):: somehow stippled brush works only  
  174.     //                      when the bitmap created on stack, not
  175.     //                      as a member of the class
  176.  
  177.     wxBitmap checker( (const char*)_gCheckerImg, 8,8 );
  178.  
  179.     wxBrush checkerBrush( checker );
  180.  
  181.     dc.SetPen( mpLayout->mNullPen );
  182.     dc.SetBrush( checkerBrush );
  183.     dc.SetLogicalFunction( wxXOR );
  184.  
  185.     if ( mHandleIsVertical )
  186.     {
  187.         int delta = pos.x - mDragOrigin.x;
  188.  
  189.         if ( !pane.IsHorizontal() )
  190.  
  191.             delta = pos.y - mDragOrigin.y;
  192.  
  193.         int realHndOfs;
  194.         realHndOfs = pane.mBoundsInParent.x + pane.mLeftMargin + mHandleOfs;
  195.  
  196.         int newX = realHndOfs + delta;
  197.  
  198.         if ( newX + resizeHndSize > mHandleDragArea.x + mHandleDragArea.width )
  199.  
  200.             newX = mHandleDragArea.x + mHandleDragArea.width  - 1;
  201.  
  202.         if ( newX < mHandleDragArea.x ) 
  203.  
  204.             newX = mHandleDragArea.x;
  205.  
  206.         mDraggedDelta = newX - realHndOfs;
  207.  
  208.         dc.DrawRectangle( newX + ofsX, mHandleDragArea.y + ofsY,
  209.                           resizeHndSize + 1,
  210.                           mHandleDragArea.height+1 );
  211.     }
  212.     else
  213.     {
  214.         // otherwise, draw horizontal handle
  215.  
  216.         int delta = pos.y - mDragOrigin.y;
  217.  
  218.         if ( !pane.IsHorizontal() )
  219.  
  220.             delta = pos.x - mDragOrigin.x;
  221.  
  222.         int realHndOfs;
  223.         realHndOfs = pane.mBoundsInParent.y + pane.mTopMargin + mHandleOfs;
  224.  
  225.         int newY = realHndOfs + delta;
  226.  
  227.         if ( newY + resizeHndSize > mHandleDragArea.y + mHandleDragArea.height )
  228.  
  229.             newY = mHandleDragArea.y + mHandleDragArea.height - 1;
  230.  
  231.         if ( newY < mHandleDragArea.y ) 
  232.  
  233.             newY = mHandleDragArea.y;
  234.  
  235.         mDraggedDelta = newY - realHndOfs;
  236.  
  237.         dc.DrawRectangle( mHandleDragArea.x + ofsX, newY + ofsY,
  238.                           mHandleDragArea.width + 1,
  239.                           resizeHndSize + 1 );
  240.     }
  241.  
  242.     dc.SetLogicalFunction( prevLF );
  243.  
  244.     // "End drawing on top (frees the window used for drawing
  245.     // over the screen)" --J.S.
  246.     wxScreenDC::EndDrawingOnTop();
  247. }
  248.  
  249. void cbPaneDrawPlugin::OnMouseMove( cbMotionEvent& event ) 
  250. {
  251.     if ( !mResizeStarted )
  252.     {
  253.         // if nothing is started, do hit-tests
  254.  
  255.         bool prevWasRowHandle = mRowHandleHitted;
  256.  
  257.         mBarContentHitted = FALSE;
  258.         mBarHandleHitted  = FALSE;
  259.         mRowHandleHitted  = FALSE;
  260.  
  261.         int testResult =  
  262.             event.mpPane->HitTestPaneItems( event.mPos,        // in pane's coordiantes
  263.                                             &mpResizedRow,
  264.                                             &mpDraggedBar );
  265.  
  266.         if ( testResult != CB_NO_ITEMS_HITTED )
  267.         {
  268.             if ( testResult == CB_BAR_CONTENT_HITTED )
  269.             {
  270.                 // restore cursor, if non of the handles were hit
  271.                 if ( mResizeCursorOn )
  272.                 {
  273.                     // remove resizing hints
  274.  
  275.                     mpLayout->ReleaseEventsFromPane( event.mpPane );
  276.                     mpLayout->ReleaseEventsFromPlugin( this );
  277.     
  278.                     mResizeCursorOn = FALSE;
  279.  
  280.                     mBarContentHitted = TRUE;
  281.  
  282.                     // In Windows, at least, the frame needs to have a null cursor
  283.                     // else child windows (such as text windows) inherit the cursor
  284. #if 1
  285.                     mpLayout->GetParentFrame().SetCursor( wxNullCursor );
  286. #else
  287.                     mpLayout->GetParentFrame().SetCursor( *mpLayout->mpNormalCursor );
  288. #endif
  289.                 }
  290.  
  291.                 // TBD:: fire something like "mouse-over-bar" event
  292.  
  293.                 event.Skip(); // pass event to the next handler in the chain
  294.                 return;
  295.             }
  296.  
  297.             wxCursor* pCurs = NULL;
  298.  
  299.             if ( testResult == CB_UPPER_ROW_HANDLE_HITTED ||
  300.                  testResult == CB_LOWER_ROW_HANDLE_HITTED)
  301.             {
  302.                 if ( event.mpPane->IsHorizontal() )
  303.  
  304.                     pCurs = mpLayout->mpVertCursor;
  305.                 else
  306.                     pCurs = mpLayout->mpHorizCursor;
  307.  
  308.                 mRowHandleHitted = TRUE;
  309.                 mIsUpperHandle    = ( testResult == CB_UPPER_ROW_HANDLE_HITTED );
  310.             }
  311.             else
  312.             {
  313.                 // otherwise, if inter-bar handle was hitted
  314.  
  315.                 if ( event.mpPane->IsHorizontal() )
  316.  
  317.                     pCurs = mpLayout->mpHorizCursor;
  318.                 else
  319.                     pCurs = mpLayout->mpVertCursor;
  320.  
  321.                 mBarHandleHitted = TRUE;
  322.                 mIsLeftHandle    = ( testResult == CB_LEFT_BAR_HANDLE_HITTED );
  323.             }
  324.  
  325.             // avoid setting the same cursor twice
  326.  
  327.             if ( !mResizeCursorOn || prevWasRowHandle != mRowHandleHitted )
  328.             {
  329.                 if ( !mResizeCursorOn )
  330.                 {
  331.                     // caputre if not captured yet
  332.                     mpLayout->CaptureEventsForPane( event.mpPane );
  333.                     mpLayout->CaptureEventsForPlugin( this );
  334.                 }
  335.  
  336.                 mpLayout->GetParentFrame().SetCursor( *pCurs );
  337.             }
  338.  
  339.             mResizeCursorOn = TRUE;
  340.  
  341.             // handled is being dragged now, thus event is "eaten" by this plugin
  342.  
  343.             return;
  344.  
  345.         } // end of if (HitTestBarHandles())
  346.  
  347.         // restore cursor, if non of the handles were hit
  348.         if ( mResizeCursorOn )
  349.         {
  350.             mpLayout->ReleaseEventsFromPane( event.mpPane );
  351.             mpLayout->ReleaseEventsFromPlugin( this );
  352.  
  353.             // In Windows, at least, the frame needs to have a null cursor
  354.             // else child windows (such as text windows) inherit the cursor
  355. #if 1
  356.             mpLayout->GetParentFrame().SetCursor( wxNullCursor );
  357. #else
  358.             mpLayout->GetParentFrame().SetCursor( *mpLayout->mpNormalCursor );
  359. #endif
  360.  
  361.             mResizeCursorOn = FALSE;
  362.         }
  363.  
  364.         event.Skip(); // pass event to the next plugin
  365.     }
  366.  
  367.     // othewise series of actions, if something has already started
  368.  
  369.     else
  370.     if ( mResizeStarted )
  371.     {
  372.         // apply xor-mask twice 
  373.         DrawDraggedHandle( mPrevPos,   *event.mpPane );
  374.  
  375.         // draw handle in the new position
  376.         DrawDraggedHandle( event.mPos, *event.mpPane );
  377.         mPrevPos = event.mPos;
  378.  
  379.         // handled is dragged, thus event is "eaten" by this plugin
  380.     }
  381.     else
  382.         event.Skip(); // pass event to the next plugin
  383. }
  384.  
  385. void cbPaneDrawPlugin::OnLDblClick( cbLeftDClickEvent& event )
  386. {
  387.     if ( !mResizeCursorOn )
  388.     {
  389.         cbBarInfo* pBarToFloat;
  390.  
  391.         if ( event.mpPane->HitTestPaneItems( event.mPos,       // in pane's coordiantes
  392.                                              &mpResizedRow,
  393.                                              &pBarToFloat ) == CB_BAR_CONTENT_HITTED
  394.            )
  395.             {
  396.             return;
  397.             }
  398.  
  399.         event.Skip();
  400.     }
  401. }
  402.  
  403. void cbPaneDrawPlugin::OnLButtonDown( cbLeftDownEvent& event ) 
  404. {
  405.     wxASSERT( !mResizeStarted );
  406.  
  407.     if ( mResizeCursorOn )
  408.     {
  409.         mResizeStarted = TRUE;
  410.         mDragOrigin    = event.mPos;
  411.         
  412.         // setup constraints for the dragging handle
  413.  
  414.         int from, till;
  415.         mHandleOfs        = 0;
  416.         mHandleIsVertical = FALSE;
  417.  
  418.         if ( mRowHandleHitted )
  419.  
  420.             event.mpPane->GetRowResizeRange( mpResizedRow, &from, &till, mIsUpperHandle );
  421.         else
  422.             // otherwise if bar handle was hitted
  423.             event.mpPane->GetBarResizeRange( mpDraggedBar, &from, &till, mIsLeftHandle );
  424.          
  425.         if ( mRowHandleHitted )
  426.         {
  427.             mHandleIsVertical = ( event.mpPane->IsHorizontal() ) ? FALSE : TRUE;
  428.  
  429.             mHandleDragArea.x      = 0;
  430.             mHandleDragArea.width  = event.mpPane->mPaneWidth;
  431.  
  432.             mHandleDragArea.y      = from;
  433.             mHandleDragArea.height = till - from;
  434.  
  435.             if ( mIsUpperHandle )
  436.  
  437.                 mHandleOfs = mpResizedRow->mRowY;
  438.             else
  439.                 mHandleOfs = mpResizedRow->mRowY + 
  440.                              mpResizedRow->mRowHeight -
  441.                              event.mpPane->mProps.mResizeHandleSize;
  442.         }
  443.         else
  444.         {
  445.             // otehrwise if bar handle dragged
  446.  
  447. //            cbRowInfo& rowInfo     = *mpDraggedBar->mpRow;
  448.             wxRect& bounds         = mpDraggedBar->mBounds;
  449.  
  450.             mHandleIsVertical = ( event.mpPane->IsHorizontal() ) ? TRUE : FALSE;
  451.  
  452.             mHandleDragArea.x      = from;
  453.             mHandleDragArea.width  = till - from;
  454.  
  455.  
  456.             mHandleDragArea.y      = bounds.y;
  457.             mHandleDragArea.height = bounds.height;
  458.  
  459.             // left-side-handle mBounds
  460.             if ( mIsLeftHandle )
  461.  
  462.                 mHandleOfs = bounds.x;
  463.             else
  464.                 mHandleOfs = bounds.x + 
  465.                              bounds.width - event.mpPane->mProps.mResizeHandleSize;
  466.  
  467.         }
  468.  
  469.         event.mpPane->PaneToFrame( &mHandleDragArea );
  470.         DrawDraggedHandle(mDragOrigin, *event.mpPane);
  471.  
  472.         mPrevPos = mDragOrigin;
  473.  
  474.         return;
  475.         // handled is dragged, thus event is "eaten" by this plugin
  476.     }
  477.     else
  478.     {
  479.         cbBarInfo* pDraggedBar;
  480.  
  481.         if ( event.mpPane->HitTestPaneItems( event.mPos,       // in pane's coordiantes
  482.                                              &mpResizedRow,
  483.                                              &pDraggedBar ) == CB_BAR_CONTENT_HITTED 
  484.            )
  485.         {
  486.             int x = event.mPos.x,
  487.                 y = event.mPos.y;
  488.  
  489.             event.mpPane->PaneToFrame( &x, &y );
  490.  
  491.             cbStartBarDraggingEvent dragEvt( pDraggedBar, wxPoint(x,y), event.mpPane );
  492.  
  493.             mpLayout->FirePluginEvent( dragEvt );
  494.  
  495.             return; // event is "eaten" by this plugin
  496.         }
  497.     }
  498.  
  499.     event.Skip(); // pass event to the next plugin in the chain
  500. }
  501.  
  502. void cbPaneDrawPlugin::OnLButtonUp( cbLeftUpEvent& event ) 
  503. {
  504.     if ( mResizeStarted )
  505.     {
  506.         DrawDraggedHandle( event.mPos, *event.mpPane );
  507.  
  508.         mResizeStarted  = FALSE;
  509.         mResizeCursorOn = FALSE;
  510.  
  511.         mpLayout->ReleaseEventsFromPane( event.mpPane );
  512.         mpLayout->ReleaseEventsFromPlugin( this );
  513.  
  514.         // In Windows, at least, the frame needs to have a null cursor
  515.         // else child windows (such as text windows) inherit the cursor
  516. #if 1
  517.         mpLayout->GetParentFrame().SetCursor( wxNullCursor );
  518. #else
  519.         mpLayout->GetParentFrame().SetCursor( *mpLayout->mpNormalCursor );
  520. #endif
  521.  
  522.         if ( mRowHandleHitted )
  523.         {
  524.             event.mpPane->ResizeRow( mpResizedRow, 
  525.                                      mDraggedDelta,
  526.                                      mIsUpperHandle );
  527.         }
  528.         else
  529.         {
  530.             event.mpPane->ResizeBar( mpDraggedBar, 
  531.                                      mDraggedDelta,
  532.                                      mIsLeftHandle );
  533.         }
  534.  
  535.         mpDraggedBar = NULL;
  536.         mpResizedRow = NULL;
  537.  
  538.         // handled dragging action was finished by this mouse-up, 
  539.         // thus event is "eaten" by this plugin
  540.  
  541.         return;
  542.     }
  543.  
  544.     event.Skip(); // pass event to the next plugin
  545. }
  546.  
  547. void cbPaneDrawPlugin::OnRButtonUp( cbRightUpEvent&   event )
  548. {
  549.     wxPoint fpos = event.mPos;
  550.     event.mpPane->PaneToFrame( &fpos.x, &fpos.y );
  551.  
  552.     cbBarInfo* pDraggedBar;
  553.  
  554.     // user clicks inside the bar contnet, fire bar-customization event
  555.  
  556.     if ( event.mpPane->HitTestPaneItems( event.mPos,       // in pane's coordiantes
  557.                                          &mpResizedRow,
  558.                                          &pDraggedBar  ) == CB_BAR_CONTENT_HITTED
  559.        )
  560.     {
  561.         cbCustomizeBarEvent cbEvt( pDraggedBar, fpos, event.mpPane );
  562.  
  563.         mpLayout->FirePluginEvent( cbEvt );
  564.  
  565.         return; // event is "eaten" by this plugin
  566.     }
  567.  
  568.     // otherwise fire whole-layout customization event
  569.  
  570.     cbCustomizeLayoutEvent csEvt( fpos );
  571.  
  572.     mpLayout->FirePluginEvent( csEvt );
  573.  
  574.     // event is "eaten" by this plugin
  575. }
  576.  
  577. void cbPaneDrawPlugin::OnSizeBarWindow( cbSizeBarWndEvent& event ) 
  578. {
  579.     cbBarInfo& bar = *event.mpBar;
  580.     mpPane         = event.mpPane;
  581.  
  582.     // it's possible that a bar does not have it's own window!
  583.     if ( !bar.mpBarWnd ) return;
  584.  
  585.     wxRect& bounds = event.mBoundsInParent;
  586.  
  587.     // check visibility
  588.     if ( bounds.height != 0 )
  589.     {
  590.         // size smaller than bounds, to leave space for shade lines
  591.  
  592.         // FIXME:: +/- 1s
  593.  
  594.         bar.mpBarWnd->wxWindow::SetSize( bounds.x      + 1 + bar.mDimInfo.mHorizGap,     
  595.                                          bounds.y      + 1 + bar.mDimInfo.mVertGap,
  596.                                          bounds.width  - 2 - bar.mDimInfo.mHorizGap*2,
  597.                                          bounds.height - 2 - bar.mDimInfo.mVertGap *2 , 
  598.                                          0 
  599.                                        );
  600.  
  601.         if ( !bar.mpBarWnd->IsShown() )
  602.  
  603.             bar.mpBarWnd->Show( TRUE );
  604.     }
  605.     else
  606.         // hide bar if not visible
  607.         bar.mpBarWnd->Show( FALSE );
  608.  
  609.     event.Skip(); // pass event to the next plugin in the chain
  610. }
  611.  
  612. void cbPaneDrawPlugin::OnDrawRowDecorations( cbDrawRowDecorEvent& event )
  613. {
  614.     DrawPaneShadeForRow( event.mpRow, *event.mpDc );
  615.  
  616.     event.Skip(); // pass event to the next plugin
  617. }
  618.  
  619. void cbPaneDrawPlugin::DrawUpperRowHandle( cbRowInfo* pRow, wxDC& dc )
  620. {
  621.     wxRect& bounds = pRow->mBoundsInParent;
  622.  
  623.     if ( mpPane->IsHorizontal() )
  624.     {
  625.          if ( pRow->mHasUpperHandle )
  626.         
  627.             mpPane->DrawHorizHandle( dc, bounds.x, 
  628.                                      bounds.y-1, 
  629.                                       pRow->mRowWidth );
  630.     }
  631.     else
  632.     {
  633.         if ( pRow->mHasUpperHandle )
  634.  
  635.             mpPane->DrawVertHandle( dc, bounds.x-1, 
  636.                                     bounds.y, pRow->mRowWidth );
  637.     }
  638. }
  639.  
  640. void cbPaneDrawPlugin::DrawLowerRowHandle( cbRowInfo* pRow, wxDC& dc )
  641. {
  642.     wxRect& bounds = pRow->mBoundsInParent;
  643.  
  644.     // check if iter-row handles present
  645.  
  646.     if ( mpPane->IsHorizontal() )
  647.     {
  648.         if ( pRow->mHasLowerHandle )
  649.         
  650.             mpPane->DrawHorizHandle( dc, bounds.x, bounds.y + bounds.height - mpPane->mProps.mResizeHandleSize - 1, 
  651.                                       pRow->mRowWidth );
  652.     }
  653.     else
  654.     {
  655.         if ( pRow->mHasLowerHandle )
  656.  
  657.             mpPane->DrawVertHandle( dc, bounds.x + bounds.width - mpPane->mProps.mResizeHandleSize - 1, 
  658.                                      bounds.y, pRow->mRowWidth );
  659.     }
  660. }
  661.  
  662. void cbPaneDrawPlugin::OnDrawRowHandles( cbDrawRowHandlesEvent& event )
  663. {
  664.     // short-cuts
  665.     cbRowInfo* pRow = event.mpRow;
  666.     wxDC&   dc      = *event.mpDc;
  667.     mpPane          = event.mpPane;
  668.  
  669.     // draw handles of surrounding rows first
  670.  
  671.     if ( pRow->mpPrev && pRow->mpPrev->mHasLowerHandle )
  672.  
  673.             DrawLowerRowHandle( pRow->mpPrev, dc );
  674.  
  675.     if ( pRow->mpNext && pRow->mpNext->mHasUpperHandle )
  676.  
  677.         DrawUpperRowHandle( pRow->mpNext, dc );
  678.  
  679.     // draw handles of the given row
  680.  
  681.     if ( pRow->mHasUpperHandle )
  682.     
  683.         DrawUpperRowHandle( pRow, dc );
  684.  
  685.     if ( pRow->mHasLowerHandle )
  686.  
  687.         DrawLowerRowHandle( pRow, dc );
  688.  
  689.     event.Skip(); // pass event to the next plugin
  690. }
  691.  
  692. void cbPaneDrawPlugin::OnDrawPaneBackground ( cbDrawPaneBkGroundEvent& event )
  693. {
  694.     wxDC& dc = *event.mpDc;
  695.     mpPane   = event.mpPane;
  696.  
  697.     // FOR NOW:: hard-coded
  698.     wxBrush bkBrush( mpLayout->mBorderPen.GetColour(), wxSOLID );
  699.  
  700.     dc.SetBrush( bkBrush );
  701.     dc.SetPen( mpLayout->mNullPen );
  702.  
  703.     wxRect& bounds = mpPane->mBoundsInParent;
  704.  
  705.     if ( mpPane->mTopMargin >= 1 )
  706.     
  707.         dc.DrawRectangle( bounds.x, bounds.y,
  708.                           bounds.width+1,
  709.                           mpPane->mTopMargin + 1);
  710.  
  711.  
  712.     if ( mpPane->mBottomMargin >= 1 )
  713.     
  714.         dc.DrawRectangle( bounds.x, 
  715.                           bounds.y + bounds.height - mpPane->mBottomMargin,
  716.                           bounds.width + 1,
  717.                           mpPane->mBottomMargin + 1);
  718.  
  719.  
  720.     if ( mpPane->mLeftMargin >= 1 )
  721.     
  722.         dc.DrawRectangle( bounds.x, 
  723.                           bounds.y + mpPane->mTopMargin - 1,
  724.                           mpPane->mLeftMargin + 1,
  725.                           bounds.height - mpPane->mTopMargin - mpPane->mBottomMargin + 2);
  726.  
  727.  
  728.     if ( mpPane->mRightMargin >= 1 )
  729.     
  730.         dc.DrawRectangle( bounds.x + bounds.width - mpPane->mRightMargin,
  731.                           bounds.y + mpPane->mTopMargin - 1,
  732.                           mpPane->mRightMargin + 1,
  733.                           bounds.height - mpPane->mTopMargin - mpPane->mBottomMargin + 2);
  734.  
  735.     event.Skip(); // pass event to the next plugin
  736. }
  737.  
  738. void cbPaneDrawPlugin::OnDrawRowBackground ( cbDrawRowBkGroundEvent& event )
  739. {
  740.     // short-cuts
  741.     cbRowInfo* pRow = event.mpRow;
  742.     wxDC&   dc      = *event.mpDc;
  743.     mpPane          = event.mpPane;
  744.  
  745.     // get ready
  746.     wxRect     rowBounds    = pRow->mBoundsInParent;
  747.     bool       isHorizontal    = event.mpPane->IsHorizontal();
  748.     
  749. //    int prevPos;
  750.  
  751.     if ( isHorizontal )
  752.     {
  753. //        prevPos = rowBounds.x;
  754.         // include one line above and below the row
  755.         --rowBounds.y;
  756.         rowBounds.height += 2;
  757.  
  758.         --rowBounds.x;
  759.         rowBounds.width  += 2;
  760.     }
  761.     else
  762.     {
  763. //        prevPos = rowBounds.y;
  764.         // include one line above and below the row
  765.         --rowBounds.x;
  766.         rowBounds.width  += 2;
  767.  
  768.         --rowBounds.y;
  769.         rowBounds.height += 2;
  770.     }
  771.  
  772. //#define TEST_BK_ERASING
  773.  
  774. #ifdef TEST_BK_ERASING
  775.  
  776.     // DBG::
  777.     wxBrush br0( wxColour(0,160,160), wxSOLID );
  778.     dc.SetBrush(br0);
  779.     dc.SetPen  ( mpLayout->mNullPen );
  780.     dc.DrawRectangle( rowBounds.x, rowBounds.y,
  781.                       rowBounds.width  + 1, 
  782.                       rowBounds.height + 1  );
  783. #endif
  784.  
  785.     wxBrush bkBrush( mpLayout->mGrayPen.GetColour(), wxSOLID );
  786.  
  787.     dc.SetPen  ( mpLayout->mNullPen );
  788.     dc.SetBrush( bkBrush );
  789.  
  790.     // fill background-recatangle of entire row area
  791.     dc.DrawRectangle( rowBounds.x, rowBounds.y,
  792.                       rowBounds.width  + 1, 
  793.                       rowBounds.height + 1  );
  794.  
  795.     dc.SetBrush( wxNullBrush );
  796.  
  797.     // draw "shaded-side-bars" for each bar
  798.     for( size_t i = 0; i != pRow->mBars.Count(); ++i )
  799.     {
  800.         wxRect& bounds = pRow->mBars[i]->mBoundsInParent;
  801.  
  802.         if ( isHorizontal )
  803.         {
  804.             DrawShade( 1, bounds, FL_ALIGN_LEFT, dc );
  805.             DrawShade( 1, bounds, FL_ALIGN_RIGHT, dc );
  806.         }
  807.         else
  808.         {
  809.             DrawShade( 1, bounds, FL_ALIGN_TOP, dc );
  810.             DrawShade( 1, bounds, FL_ALIGN_BOTTOM, dc );
  811.         }
  812.     }
  813.  
  814.     // draw extra shades to simulate "glued-bricks" effect
  815.  
  816.     // TBD:: reduce exessive drawing of shades, when the
  817.     //       row handle is present, and shades will be overr-drawn anyway
  818.  
  819.     DrawUpperRowShades( pRow, dc, 1 ); // outer shade
  820.  
  821.     if ( pRow->mpPrev )
  822.     {
  823.         DrawLowerRowShades( pRow->mpPrev, dc, 1 ); // outter shade
  824.         DrawLowerRowShades( pRow->mpPrev, dc, 0 ); // inner shade
  825.     }
  826.  
  827.     DrawLowerRowShades( pRow, dc, 1 );
  828.  
  829.     if ( pRow->mpNext )
  830.     {
  831.         DrawUpperRowShades( pRow->mpNext, dc, 1 ); 
  832.         DrawUpperRowShades( pRow->mpNext, dc, 0 );
  833.     }
  834.  
  835.     event.Skip(); // pass event to the next plugin
  836. }
  837.  
  838. void cbPaneDrawPlugin::DrawUpperRowShades( cbRowInfo* pRow, wxDC& dc, int level )
  839. {
  840.     for( size_t i = 0; i != pRow->mBars.Count(); ++i )
  841.     {
  842.         wxRect& bounds = pRow->mBars[i]->mBoundsInParent;
  843.  
  844.         if ( mpPane->IsHorizontal() )
  845.         {        
  846.             DrawShade( level, bounds, FL_ALIGN_TOP, dc );
  847.             if ( level == 1 )
  848.             {
  849.                 dc.SetPen( mpLayout->mDarkPen );
  850.                 dc.DrawPoint( bounds.x - 1, bounds.y );
  851.                 dc.SetPen( mpLayout->mLightPen );
  852.                 dc.DrawPoint( bounds.x + bounds.width , bounds.y );
  853.             }
  854.         }
  855.         else
  856.         {
  857.             DrawShade( level, bounds, FL_ALIGN_LEFT, dc );
  858.             if ( level == 1 )
  859.             {
  860.                 dc.SetPen( mpLayout->mDarkPen );
  861.                 dc.DrawPoint( bounds.x, bounds.y -1 );
  862.                 dc.SetPen( mpLayout->mLightPen );
  863.                 dc.DrawPoint( bounds.x, bounds.y + bounds.height );
  864.             }
  865.         }
  866.     }
  867. }
  868.  
  869. void cbPaneDrawPlugin::DrawLowerRowShades( cbRowInfo* pRow, wxDC& dc, int level )
  870. {
  871.     for( size_t i = 0; i != pRow->mBars.Count(); ++i )
  872.     {
  873.         wxRect& bounds = pRow->mBars[i]->mBoundsInParent;
  874.  
  875.         if ( mpPane->IsHorizontal() )
  876.         {
  877.             DrawShade( level, bounds, FL_ALIGN_BOTTOM, dc );
  878.             if ( level == 1 )
  879.             {
  880.                 dc.SetPen( mpLayout->mDarkPen );
  881.                 dc.DrawPoint( bounds.x - 1, bounds.y + bounds.height -1 );
  882.                 dc.SetPen( mpLayout->mLightPen );
  883.                 dc.DrawPoint( bounds.x + bounds.width , bounds.y + bounds.height -1 );
  884.             }
  885.         }
  886.         else
  887.         {
  888.             DrawShade( level, bounds, FL_ALIGN_RIGHT, dc );
  889.             if ( level == 1 )
  890.             {
  891.                 dc.SetPen( mpLayout->mDarkPen );
  892.                 dc.DrawPoint( bounds.x + bounds.width - 1, bounds.y -1 );
  893.                 dc.SetPen( mpLayout->mLightPen );
  894.                 dc.DrawPoint( bounds.x + bounds.width - 1, bounds.y + bounds.height );
  895.             }
  896.         }
  897.     }
  898. }
  899.  
  900. void cbPaneDrawPlugin::DrawBarInnerShadeRect( cbBarInfo* pBar, wxDC& dc )
  901. {
  902.     wxRect& bounds = pBar->mBoundsInParent;
  903.  
  904.     dc.SetPen( mpLayout->mDarkPen );
  905.     
  906.     dc.DrawLine( bounds.x + bounds.width - 1,
  907.                  bounds.y,
  908.                  bounds.x + bounds.width - 1,
  909.                  bounds.y + bounds.height );
  910.  
  911.     dc.DrawLine( bounds.x,
  912.                  bounds.y + bounds.height - 1,
  913.                  bounds.x + bounds.width,
  914.                  bounds.y + bounds.height -1  );
  915.  
  916.     dc.SetPen( mpLayout->mLightPen );
  917.  
  918.     dc.DrawLine( bounds.x,
  919.                  bounds.y,
  920.                  bounds.x + bounds.width - 1,
  921.                  bounds.y );
  922.  
  923.     dc.DrawLine( bounds.x,
  924.                  bounds.y,
  925.                  bounds.x,
  926.                  bounds.y + bounds.height - 1 );
  927. }
  928.  
  929. void cbPaneDrawPlugin::DrawShade( int level, wxRect& rect, int alignment, wxDC& dc )
  930. {
  931.     // simulates "guled-bricks" appearence of control bars
  932.  
  933.     if ( ( alignment == FL_ALIGN_TOP    && level == 1 ) ||
  934.          ( alignment == FL_ALIGN_BOTTOM && level == 0 ) ||
  935.          ( alignment == FL_ALIGN_LEFT   && level == 1 ) ||
  936.          ( alignment == FL_ALIGN_RIGHT  && level == 0 )
  937.        )
  938.     
  939.         dc.SetPen( mpLayout->mDarkPen  );
  940.     else
  941.         dc.SetPen( mpLayout->mLightPen );
  942.  
  943.     if ( alignment == FL_ALIGN_TOP )
  944.     {
  945.         if ( level == 0 )
  946.         
  947.             dc.DrawLine( rect.x, 
  948.                          rect.y,
  949.                          rect.x + rect.width - 1,
  950.                          rect.y );
  951.         else
  952.             dc.DrawLine( rect.x - 1,
  953.                          rect.y - 1,
  954.                          rect.x + rect.width + 0,
  955.                          rect.y - 1 );
  956.     }
  957.     else
  958.     if ( alignment == FL_ALIGN_BOTTOM )
  959.     {
  960.         if ( level == 0 )
  961.         
  962.             dc.DrawLine( rect.x, 
  963.                          rect.y + rect.height - 1,
  964.                          rect.x + rect.width,
  965.                          rect.y + rect.height - 1 );
  966.         else
  967.             dc.DrawLine( rect.x - 1,
  968.                          rect.y + rect.height,
  969.                          rect.x + rect.width + 1,
  970.                          rect.y + rect.height );
  971.     }
  972.     else
  973.     if ( alignment == FL_ALIGN_LEFT )
  974.     {
  975.         if ( level == 0 )
  976.         
  977.             dc.DrawLine( rect.x, 
  978.                          rect.y,
  979.                          rect.x,
  980.                          rect.y + rect.height - 1 );
  981.         else
  982.             dc.DrawLine( rect.x - 1,
  983.                          rect.y - 1,
  984.                          rect.x - 1,
  985.                          rect.y + rect.height );
  986.     }
  987.     else
  988.     if ( alignment == FL_ALIGN_RIGHT )
  989.     {
  990.         if ( level == 0 )
  991.         
  992.             dc.DrawLine( rect.x + rect.width - 1, 
  993.                          rect.y,
  994.                          rect.x + rect.width - 1,
  995.                          rect.y + rect.height );
  996.         else
  997.         {                     
  998.             dc.DrawLine( rect.x + rect.width,
  999.                          rect.y - 1,
  1000.                          rect.x + rect.width,
  1001.                          rect.y + rect.height + 1  );
  1002.         }
  1003.     }
  1004. }
  1005.  
  1006. void cbPaneDrawPlugin::DrawShade1( int level, wxRect& rect, int alignment, wxDC& dc )
  1007. {
  1008.     // simulates "guled-bricks" appearence of control bars
  1009.  
  1010.     if ( ( alignment == FL_ALIGN_TOP    && level == 1 ) ||
  1011.          ( alignment == FL_ALIGN_BOTTOM && level == 0 ) ||
  1012.          ( alignment == FL_ALIGN_LEFT   && level == 1 ) ||
  1013.          ( alignment == FL_ALIGN_RIGHT  && level == 0 )
  1014.        )
  1015.     
  1016.         dc.SetPen( mpLayout->mDarkPen  );
  1017.     else
  1018.         dc.SetPen( mpLayout->mLightPen );
  1019.  
  1020.     if ( alignment == FL_ALIGN_TOP )
  1021.     {
  1022.         if ( level == 0 )
  1023.         
  1024.             dc.DrawLine( rect.x, 
  1025.                          rect.y,
  1026.                          rect.x + rect.width,
  1027.                          rect.y );
  1028.         else
  1029.             dc.DrawLine( rect.x,
  1030.                          rect.y - 1,
  1031.                          rect.x + rect.width,
  1032.                          rect.y - 1 );
  1033.     }
  1034.     else
  1035.     if ( alignment == FL_ALIGN_BOTTOM )
  1036.     {
  1037.         if ( level == 0 )
  1038.         
  1039.             dc.DrawLine( rect.x, 
  1040.                          rect.y + rect.height - 1,
  1041.                          rect.x + rect.width,
  1042.                          rect.y + rect.height - 1 );
  1043.         else
  1044.             dc.DrawLine( rect.x,
  1045.                          rect.y + rect.height,
  1046.                          rect.x + rect.width,
  1047.                          rect.y + rect.height );
  1048.     }
  1049.     else
  1050.     if ( alignment == FL_ALIGN_LEFT )
  1051.     {
  1052.         if ( level == 0 )
  1053.         
  1054.             dc.DrawLine( rect.x, 
  1055.                          rect.y,
  1056.                          rect.x,
  1057.                          rect.y + rect.height );
  1058.         else
  1059.             dc.DrawLine( rect.x - 1,
  1060.                          rect.y,
  1061.                          rect.x - 1,
  1062.                          rect.y + rect.height );
  1063.     }
  1064.     else
  1065.     if ( alignment == FL_ALIGN_RIGHT )
  1066.     {
  1067.         if ( level == 0 )
  1068.         
  1069.             dc.DrawLine( rect.x + rect.width - 1, 
  1070.                          rect.y,
  1071.                          rect.x + rect.width - 1,
  1072.                          rect.y + rect.height );
  1073.         else
  1074.         {                     
  1075.             dc.DrawLine( rect.x + rect.width,
  1076.                          rect.y ,
  1077.                          rect.x + rect.width,
  1078.                          rect.y + rect.height );
  1079.         }
  1080.     }
  1081. }
  1082.  
  1083. void cbPaneDrawPlugin::DrawPaneShade( wxDC& dc, int alignment )
  1084. {
  1085.     if ( !mpPane->mProps.mShow3DPaneBorderOn ) return;
  1086.  
  1087.     wxRect bounds = mpPane->mBoundsInParent;
  1088.  
  1089.     bounds.x      += mpPane->mLeftMargin;
  1090.     bounds.y      += mpPane->mTopMargin;
  1091.     bounds.width  -= ( mpPane->mLeftMargin + mpPane->mRightMargin  );
  1092.     bounds.height -= ( mpPane->mTopMargin  + mpPane->mBottomMargin );
  1093.  
  1094.     DrawShade( 0, bounds, alignment, dc );
  1095.     DrawShade( 1, bounds, alignment, dc );
  1096. }
  1097.  
  1098. void cbPaneDrawPlugin::DrawPaneShadeForRow( cbRowInfo* pRow, wxDC& dc )
  1099. {
  1100.     if ( !mpPane->mProps.mShow3DPaneBorderOn ) return;
  1101.  
  1102.     // do not draw decoration, if pane has "vainished"
  1103.     if ( mpPane->mPaneWidth  < 0 ||
  1104.          mpPane->mPaneHeight < 0 )
  1105.  
  1106.          return;
  1107.  
  1108.     wxRect bounds = pRow->mBoundsInParent;
  1109.  
  1110.     if ( mpPane->mAlignment == FL_ALIGN_TOP ||
  1111.          mpPane->mAlignment == FL_ALIGN_BOTTOM )
  1112.     {
  1113.         --bounds.y;
  1114.         bounds.height += 2;
  1115.  
  1116.         DrawShade1( 0, bounds, FL_ALIGN_LEFT, dc );
  1117.         DrawShade1( 1, bounds, FL_ALIGN_LEFT, dc );
  1118.         DrawShade1( 0, bounds, FL_ALIGN_RIGHT, dc );
  1119.         DrawShade1( 1, bounds, FL_ALIGN_RIGHT, dc );
  1120.  
  1121.         if ( !pRow->mpNext )
  1122.             DrawPaneShade( dc, FL_ALIGN_BOTTOM );
  1123.  
  1124.         if ( !pRow->mpPrev )
  1125.             DrawPaneShade( dc, FL_ALIGN_TOP );
  1126.     }
  1127.     else
  1128.     {
  1129.         --bounds.x;
  1130.         bounds.width += 2;
  1131.  
  1132.         DrawShade1( 0, bounds, FL_ALIGN_TOP, dc );
  1133.         DrawShade1( 1, bounds, FL_ALIGN_TOP, dc );
  1134.         DrawShade1( 0, bounds, FL_ALIGN_BOTTOM, dc );
  1135.         DrawShade1( 1, bounds, FL_ALIGN_BOTTOM, dc );
  1136.  
  1137.         if ( !pRow->mpNext )
  1138.             DrawPaneShade( dc, FL_ALIGN_RIGHT );
  1139.  
  1140.         if ( !pRow->mpPrev )
  1141.             DrawPaneShade( dc, FL_ALIGN_LEFT );
  1142.     }
  1143. }
  1144.  
  1145. void cbPaneDrawPlugin::OnDrawPaneDecorations( cbDrawPaneDecorEvent& event )
  1146. {
  1147.     wxDC& dc = *event.mpDc;
  1148.  
  1149.     cbDockPane* pPane = event.mpPane;
  1150.  
  1151.     RowArrayT& lst = pPane->GetRowList();
  1152.     
  1153.     // FIXME:: this is a workaround for some glitches
  1154.  
  1155.     if ( lst.Count() )
  1156.     {
  1157.         cbRowInfo* pLastRow = lst[ lst.Count() - 1 ];
  1158.  
  1159.         pPane->PaintRowBackground( pLastRow,  dc );
  1160.         pPane->PaintRowDecorations( pLastRow, dc );
  1161.         pPane->PaintRowHandles( pLastRow, dc );
  1162.     }
  1163.  
  1164.     if ( !pPane->mProps.mShow3DPaneBorderOn ) return;
  1165.  
  1166.     // do not draw decoration, if pane is completely hidden
  1167.     if ( event.mpPane->mPaneWidth  < 0 ||
  1168.          event.mpPane->mPaneHeight < 0 )
  1169.  
  1170.          return;
  1171.  
  1172.     DrawPaneShade( dc, FL_ALIGN_TOP    );
  1173.     DrawPaneShade( dc, FL_ALIGN_BOTTOM );
  1174.     DrawPaneShade( dc, FL_ALIGN_LEFT   );
  1175.     DrawPaneShade( dc, FL_ALIGN_RIGHT  );
  1176.  
  1177.     event.Skip(); // pass event to the next plugin
  1178. }
  1179.  
  1180. // bar decoration/sizing handlers
  1181.  
  1182. void cbPaneDrawPlugin::OnDrawBarDecorations( cbDrawBarDecorEvent& event )
  1183. {
  1184. //    cbBarInfo* pBar = event.mpBar;
  1185.     wxDC&   dc      = *event.mpDc;
  1186.  
  1187.     // draw brick borders
  1188.  
  1189.     wxRect& rect = event.mBoundsInParent;
  1190.  
  1191.     dc.SetPen( mpLayout->mLightPen );
  1192.  
  1193.     // horiz
  1194.     dc.DrawLine( rect.x, rect.y, 
  1195.                  rect.x + rect.width-1, rect.y );
  1196.  
  1197.     // vert
  1198.     dc.DrawLine( rect.x, rect.y,
  1199.                  rect.x, rect.y + rect.height-1 );
  1200.  
  1201.  
  1202.     dc.SetPen( mpLayout->mDarkPen );
  1203.  
  1204.     // vert
  1205.     dc.DrawLine( rect.x + rect.width-1, rect.y,
  1206.                  rect.x + rect.width-1, rect.y + rect.height-1 );
  1207.  
  1208.     // horiz
  1209.     dc.DrawLine( rect.x, rect.y + rect.height-1,
  1210.                  rect.x + rect.width, rect.y + rect.height-1 );
  1211.  
  1212.     event.Skip(); // pass event to the next plugin
  1213. }
  1214.  
  1215. void cbPaneDrawPlugin::OnDrawBarHandles( cbDrawBarHandlesEvent& event )
  1216. {
  1217.     // short-cuts
  1218.     cbBarInfo* pBar = event.mpBar;
  1219.     wxDC&   dc      = *event.mpDc;
  1220.     mpPane          = event.mpPane;
  1221.  
  1222.     // draw handles around the bar if present
  1223.  
  1224.     if ( pBar->mHasLeftHandle ||
  1225.          pBar->mHasRightHandle )
  1226.     {
  1227.         wxRect& bounds = pBar->mBoundsInParent;
  1228.  
  1229.         if ( mpPane->IsHorizontal() )
  1230.         {
  1231.             if ( pBar->mHasLeftHandle )
  1232.  
  1233.                 mpPane->DrawVertHandle( dc, bounds.x - mpPane->mProps.mResizeHandleSize -1, 
  1234.                                         bounds.y, bounds.height );
  1235.  
  1236.             if ( pBar->mHasRightHandle )
  1237.  
  1238.                 mpPane->DrawVertHandle( dc, 
  1239.                                         bounds.x + bounds.width -1, 
  1240.                                         bounds.y, bounds.height );
  1241.         }
  1242.         else
  1243.         {
  1244.             if ( pBar->mHasLeftHandle )
  1245.  
  1246.                 mpPane->DrawHorizHandle( dc, bounds.x, 
  1247.                                          bounds.y  - mpPane->mProps.mResizeHandleSize - 1, 
  1248.                                          bounds.width );
  1249.  
  1250.             if ( pBar->mHasRightHandle )
  1251.  
  1252.                 mpPane->DrawHorizHandle( dc, bounds.x, 
  1253.                                          bounds.y + bounds.height - 1,
  1254.                                          bounds.width );
  1255.         }
  1256.     }
  1257.  
  1258.     event.Skip(); // pass event to the next plugin
  1259. }
  1260.  
  1261. void cbPaneDrawPlugin::OnStartDrawInArea( cbStartDrawInAreaEvent& event )
  1262. {
  1263.     // DBG::
  1264.     wxASSERT( mpClntDc == NULL );
  1265.  
  1266.     // FOR NOW:: create/destroy client-dc upon each drawing
  1267.     mpClntDc = new wxClientDC( &mpLayout->GetParentFrame() );
  1268.  
  1269.     (*event.mppDc) = mpClntDc;
  1270.  
  1271.     mpClntDc->SetClippingRegion( event.mArea.x,     event.mArea.y,
  1272.                                  event.mArea.width, event.mArea.height );
  1273. }
  1274.  
  1275. void cbPaneDrawPlugin::OnFinishDrawInArea( cbFinishDrawInAreaEvent& event )
  1276. {
  1277.     // DBG::
  1278.     wxASSERT( mpClntDc );
  1279.  
  1280.     delete mpClntDc;
  1281.  
  1282.     mpClntDc = NULL;
  1283. }
  1284.  
  1285.