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 / controlbar.cpp < prev    next >
C/C++ Source or Header  |  2002-12-22  |  88KB  |  3,565 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        controlbar.cpp
  3. // Purpose:     Implementation for main controlbar classes.
  4. // Author:      Aleksandras Gluchovas
  5. // Modified by:
  6. // Created:     06/09/98
  7. // RCS-ID:      $Id: controlbar.cpp,v 1.12.2.1 2002/12/22 12:19:15 JS Exp $
  8. // Copyright:   (c) Aleksandras Gluchovas
  9. // Licence:     wxWindows license
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. #ifdef __GNUG__
  13.     #pragma implementation "controlbar.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/string.h"
  31. #include "wx/utils.h"     // import wxMin,wxMax macros
  32. #include "wx/minifram.h"
  33.  
  34. #include "wx/fl/controlbar.h"
  35.  
  36. // import classes of default plugins
  37.  
  38. #include "wx/fl/panedrawpl.h"
  39. #include "wx/fl/rowlayoutpl.h"
  40. #include "wx/fl/antiflickpl.h"
  41. #include "wx/fl/bardragpl.h"
  42. #include "wx/fl/cbcustom.h"
  43.  
  44. #include "wx/fl/gcupdatesmgr.h"   // import default updates manager class ("garbage-collecting" one)
  45. #include "wx/fl/updatesmgr.h"
  46.  
  47. #include "wx/fl/toolwnd.h"
  48.  
  49. // These are the event IDs being initialized to a value to
  50. // meet the new event paradigm as of wx2.3.0.  Probably we
  51. // should find a way to make these be non-global, but this
  52. // works for right now.
  53.     wxEventType cbEVT_PL_LEFT_DOWN = wxNewEventType();
  54.     wxEventType cbEVT_PL_LEFT_UP = wxNewEventType();
  55.     wxEventType cbEVT_PL_RIGHT_DOWN = wxNewEventType();
  56.     wxEventType cbEVT_PL_RIGHT_UP = wxNewEventType();
  57.     wxEventType cbEVT_PL_MOTION = wxNewEventType();
  58.  
  59.     wxEventType cbEVT_PL_LEFT_DCLICK = wxNewEventType();
  60.  
  61.     wxEventType cbEVT_PL_LAYOUT_ROW = wxNewEventType();
  62.     wxEventType cbEVT_PL_RESIZE_ROW = wxNewEventType();
  63.     wxEventType cbEVT_PL_LAYOUT_ROWS = wxNewEventType();
  64.     wxEventType cbEVT_PL_INSERT_BAR = wxNewEventType();
  65.     wxEventType cbEVT_PL_RESIZE_BAR = wxNewEventType();
  66.     wxEventType cbEVT_PL_REMOVE_BAR = wxNewEventType();
  67.     wxEventType cbEVT_PL_SIZE_BAR_WND = wxNewEventType();
  68.  
  69.     wxEventType cbEVT_PL_DRAW_BAR_DECOR = wxNewEventType();
  70.     wxEventType cbEVT_PL_DRAW_ROW_DECOR = wxNewEventType();
  71.     wxEventType cbEVT_PL_DRAW_PANE_DECOR = wxNewEventType();
  72.     wxEventType cbEVT_PL_DRAW_BAR_HANDLES = wxNewEventType();
  73.     wxEventType cbEVT_PL_DRAW_ROW_HANDLES = wxNewEventType();
  74.     wxEventType cbEVT_PL_DRAW_ROW_BKGROUND = wxNewEventType();
  75.     wxEventType cbEVT_PL_DRAW_PANE_BKGROUND = wxNewEventType();
  76.  
  77.     wxEventType cbEVT_PL_START_BAR_DRAGGING = wxNewEventType();
  78.     wxEventType cbEVT_PL_DRAW_HINT_RECT = wxNewEventType();
  79.  
  80.     wxEventType cbEVT_PL_START_DRAW_IN_AREA = wxNewEventType();
  81.     wxEventType cbEVT_PL_FINISH_DRAW_IN_AREA = wxNewEventType();
  82.  
  83.     wxEventType cbEVT_PL_CUSTOMIZE_BAR = wxNewEventType();
  84.     wxEventType cbEVT_PL_CUSTOMIZE_LAYOUT = wxNewEventType();
  85.  
  86.     wxEventType wxCUSTOM_CB_PLUGIN_EVENTS_START_AT = wxNewEventType();
  87.  
  88. // some ascii-art, still can't get these *nice* cursors working on wx... :-(
  89.  
  90. static const char* _gHorizCursorImg[] = 
  91. {
  92.     "............XX....XX............",
  93.     "............XX....XX............",
  94.     "............XX....XX............",
  95.     "............XX....XX............",
  96.     "............XX....XX............",
  97.     "...X........XX....XX........X...",
  98.     "..XX........XX....XX........XX..",
  99.     ".XXX........XX....XX........XXX.",
  100.     "XXXXXXXXXXXXXX....XXXXXXXXXXXXXX",
  101.     ".XXX........XX....XX........XXX.",
  102.     "..XX........XX....XX........XX..",
  103.     "...X........XX....XX........X...",
  104.     "............XX....XX............",
  105.     "............XX....XX............",
  106.     "............XX....XX............",
  107.     "............XX....XX............"
  108. };
  109.  
  110. static const char* _gVertCursorImg[] = 
  111. {
  112.     "................X...............",
  113.     "...............XXX..............",
  114.     "..............XXXXX.............",
  115.     ".............XXXXXXX............",
  116.     "................X...............",
  117.     "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  118.     "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  119.     "................................",
  120.     "................................",
  121.     "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  122.     "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  123.     "................X...............",
  124.     ".............XXXXXXX............",
  125.     "..............XXXXX.............",
  126.     "...............XXX..............",
  127.     "................X..............."
  128. };
  129.  
  130. // helper inline functions
  131.  
  132. static inline bool rect_contains_point( const wxRect& rect, int x, int y )
  133. {
  134.     return ( x >= rect.x &&
  135.              y >= rect.y &&
  136.              x <  rect.x + rect.width  &&
  137.              y <  rect.y + rect.height );
  138. }
  139.  
  140. static inline bool rect_hits_rect( const wxRect& r1, const wxRect& r2 )
  141. {
  142.     if ( ( r2.x >= r1.x && r2.x <= r1.x + r1.width ) ||
  143.          ( r1.x >= r2.x && r1.x <= r2.x + r2.width ) )
  144.  
  145.         if ( ( r2.y >= r1.y && r2.y <= r1.y + r1.height ) ||
  146.              ( r1.y >= r2.y && r1.y <= r2.y + r2.height ) )
  147.              
  148.             return 1;
  149.  
  150.     return 0;
  151. }
  152.  
  153. static inline void hide_rect( wxRect& r )
  154. {
  155.     r.x = 32768;
  156.     r.y = 32768;
  157.     r.width  = 1;
  158.     r.height = 1;
  159. }
  160.  
  161. static inline void clip_rect_against_rect( wxRect& r1, const wxRect& r2 )
  162. {
  163.     if ( r1.x < r2.x              || 
  164.          r1.y < r2.y              ||
  165.          r1.x >= r2.x + r2.width  ||
  166.          r1.y >= r2.y + r2.height 
  167.        ) 
  168.     {
  169.         hide_rect( r1 );
  170.         return;
  171.     }
  172.     else
  173.     {
  174.         if ( r1.x + r1.width  > r2.x + r2.width )
  175.  
  176.             r1.width = r2.x + r2.width - r1.x;
  177.  
  178.         if ( r1.y + r1.height > r2.y + r2.height )
  179.  
  180.             r1.height = r2.y + r2.height - r1.y;
  181.     }
  182. }
  183.  
  184. /***** Implementation for class cbBarSpy *****/
  185.  
  186. IMPLEMENT_DYNAMIC_CLASS( cbBarSpy, wxEvtHandler )
  187.  
  188. cbBarSpy::cbBarSpy(void)
  189.     : mpLayout(0),
  190.       mpBarWnd(0)
  191. {}
  192.  
  193. cbBarSpy::cbBarSpy( wxFrameLayout* pPanel ) 
  194.  
  195.     : mpLayout(pPanel),
  196.       mpBarWnd(0)
  197. {}
  198.  
  199. void cbBarSpy::SetBarWindow( wxWindow* pWnd )
  200. {
  201.     mpBarWnd = pWnd;
  202. }
  203.  
  204. bool cbBarSpy::ProcessEvent(wxEvent& event)
  205. {
  206.     bool handled = wxEvtHandler::ProcessEvent( event );
  207.  
  208.     int type = event.GetEventType();
  209.  
  210.     if ( !handled && ( type == wxEVT_LEFT_DOWN ||
  211.                        type == wxEVT_LEFT_DCLICK ) )
  212.     {
  213.         wxMouseEvent& mevent = *((wxMouseEvent*)&event);
  214.  
  215.         int x = mevent.m_x;
  216.         int y = mevent.m_y;
  217.  
  218.         mpBarWnd->ClientToScreen( &x, &y );
  219.         mpLayout->GetParentFrame().ScreenToClient( &x, &y );
  220.  
  221.         mevent.m_x = x;
  222.         mevent.m_y = y;
  223.  
  224.         // forwared not-handled event to frame-layout
  225.  
  226.         if ( type == wxEVT_LEFT_DOWN )
  227.         {
  228.             //mpLayout->OnLButtonDown( mevent );
  229.             event.Skip();
  230.         }
  231.         else
  232.             mpLayout->OnLDblClick( mevent );
  233.  
  234.         //event.Skip(FALSE);
  235.     }
  236.  
  237.     return handled;
  238. }
  239.  
  240. /***** Implementation for class wxFrameLayout *****/
  241.  
  242. IMPLEMENT_DYNAMIC_CLASS( wxFrameLayout, wxEvtHandler )
  243.  
  244. BEGIN_EVENT_TABLE( wxFrameLayout, wxEvtHandler )
  245.  
  246.     EVT_PAINT      ( wxFrameLayout::OnPaint       )
  247.     EVT_SIZE       ( wxFrameLayout::OnSize        )
  248.     EVT_LEFT_DOWN  ( wxFrameLayout::OnLButtonDown )
  249.     EVT_LEFT_UP    ( wxFrameLayout::OnLButtonUp   )
  250.     EVT_RIGHT_DOWN ( wxFrameLayout::OnRButtonDown )
  251.     EVT_RIGHT_UP   ( wxFrameLayout::OnRButtonUp   )
  252.     EVT_MOTION     ( wxFrameLayout::OnMouseMove   )
  253.  
  254.     EVT_LEFT_DCLICK( wxFrameLayout::OnLDblClick   )
  255.  
  256.     EVT_IDLE       ( wxFrameLayout::OnIdle        )
  257.     EVT_SET_FOCUS  ( wxFrameLayout::OnSetFocus    )
  258.     EVT_KILL_FOCUS ( wxFrameLayout::OnKillFocus   )
  259.  
  260.     EVT_ACTIVATE   ( wxFrameLayout::OnActivate    )
  261.  
  262.     EVT_ERASE_BACKGROUND( wxFrameLayout::OnEraseBackground )
  263.  
  264. END_EVENT_TABLE()
  265.  
  266. // FIXME:: how to eliminate these cut&pasted constructors?
  267.  
  268. wxFrameLayout::wxFrameLayout(void)
  269.  
  270.     : mpFrame      ( NULL ),
  271.       mpFrameClient( NULL ),
  272.  
  273.       mDarkPen  ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID ),
  274.       mLightPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DHILIGHT), 1, wxSOLID ),
  275.       mGrayPen  ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ),
  276.       mBlackPen ( wxColour(  0,  0,  0), 1, wxSOLID ),
  277.       mBorderPen( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ),
  278.    
  279.       mNullPen( wxColour(0,0,0), 1, wxTRANSPARENT ),
  280.  
  281.       mpPaneInFocus( NULL ),
  282.       mpLRUPane    ( NULL ),
  283.  
  284.  
  285.       mpTopPlugin   ( NULL ),
  286.       mpCaputesInput( NULL ),
  287.  
  288.       mClientWndRefreshPending( FALSE ),
  289.       mRecalcPending( TRUE ),
  290.       mCheckFocusWhenIdle( FALSE )
  291. {
  292.     CreateCursors();
  293.  
  294.     int i;
  295.     for ( i = 0; i != MAX_PANES; ++i )
  296.         mPanes[i]  = NULL;
  297.  
  298.     mFloatingOn = CanReparent();
  299. }
  300.  
  301. wxFrameLayout::wxFrameLayout( wxWindow* pParentFrame, wxWindow* pFrameClient, bool activateNow )
  302.  
  303.     : mpFrame( pParentFrame ),
  304.       mpFrameClient(pFrameClient),
  305.  
  306.       mDarkPen  ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID ),
  307.       mLightPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DHILIGHT), 1, wxSOLID ),
  308.       mGrayPen  ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ),
  309.       mBlackPen ( wxColour(  0,  0,  0), 1, wxSOLID ),
  310.       mBorderPen( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ),
  311.       
  312.       mNullPen( wxColour(0,0,0), 1, wxTRANSPARENT ),
  313.  
  314.       mpPaneInFocus( NULL ),
  315.       mpLRUPane    ( NULL ),
  316.       
  317.       mFloatingOn   ( TRUE ),
  318.                  
  319.       mpTopPlugin   ( NULL ),
  320.       mpCaputesInput( NULL ),
  321.       
  322.       mClientWndRefreshPending( FALSE ),
  323.       mRecalcPending( TRUE ),
  324.       mCheckFocusWhenIdle( FALSE ),
  325.       
  326.       mpUpdatesMgr( NULL )
  327. {
  328.     CreateCursors();
  329.  
  330.     int i;
  331.     for ( i = 0; i != MAX_PANES; ++i )
  332.         mPanes[i]  = new cbDockPane( i, this );
  333.  
  334.     if ( activateNow )
  335.     {
  336.         HookUpToFrame();
  337.  
  338.         // FOR NOW::
  339.         // DBG:: set RED color of frame's background for the
  340.         //       prurpose of tracking engine bugs "visually"
  341.  
  342.         GetParentFrame().SetBackgroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE) );
  343.     }
  344.  
  345.     mFloatingOn = CanReparent();
  346. }
  347.  
  348. // NOTE:: below are the only platform-check "ifdef"s in the docking system!
  349.  
  350. bool wxFrameLayout::CanReparent()
  351. {
  352. #ifdef __WXMSW__
  353.     return TRUE;
  354. #elif defined (__WXGTK__)
  355.     //return TRUE;
  356.     return FALSE;
  357. #else
  358.  
  359.     return FALSE; // reparenting is not yet supported by Motif and others
  360. #endif
  361. }
  362.  
  363. /*
  364. #ifdef __WXMSW__
  365.     #inlcude "windows.h"
  366. #endif
  367. */
  368.  
  369. void wxFrameLayout::ReparentWindow( wxWindow* pChild, wxWindow* pNewParent )
  370. {
  371. #ifdef __WXMSW__
  372. #if 0
  373.  
  374.     if ( pChild->GetParent() )
  375.     {
  376.         bool success = pChild->GetParent()->GetChildren().DeleteObject( pChild );
  377.  
  378.         wxASSERT( success ); // DBG::
  379.     }
  380.  
  381.     ::SetParent( (HWND)pChild->m_hWnd, (HWND)pNewParent->m_hWnd  );
  382.  
  383.     pNewParent->GetChildren().Append( pChild );
  384.  
  385.     pChild->SetParent( pNewParent );
  386. #endif
  387.     pChild->Reparent(pNewParent);
  388.  
  389.     return;
  390. #elif defined(__WXGTK__) || defined(__WXX11__)
  391.     // FOR NOW:: floating with wxGtk still very buggy
  392.  
  393.     return;
  394.  
  395.     //pChild->ReParent( pNewParent );
  396.  
  397.     //return;
  398. #else
  399.     wxMessageBox( "Sorry, docking is not supported for ports other than MSW and wxGTK" );
  400. #endif
  401. }
  402.  
  403. void wxFrameLayout::DestroyBarWindows()
  404. {
  405.     wxNode* pSpy = mBarSpyList.First();
  406.  
  407.     while( pSpy )
  408.     {
  409.         cbBarSpy& spy = *((cbBarSpy*)pSpy->Data());
  410.  
  411.         if ( spy.mpBarWnd->GetEventHandler() == &spy )
  412.  
  413.             spy.mpBarWnd->PopEventHandler();
  414.  
  415.         delete &spy;
  416.  
  417.         pSpy = pSpy->Next();
  418.     }
  419.  
  420.     mBarSpyList.Clear();
  421.  
  422.     size_t i;
  423.     for ( i = 0; i != mAllBars.Count(); ++i )
  424.     {
  425.         if ( mAllBars[i]->mpBarWnd )
  426.         {
  427.             mAllBars[i]->mpBarWnd->Destroy();
  428.             mAllBars[i]->mpBarWnd = NULL;
  429.         }
  430.     }
  431. }
  432.  
  433. void wxFrameLayout::ShowFloatedWindows( bool show )
  434. {
  435.     wxNode* pNode = mFloatedFrames.First();
  436.  
  437.     while( pNode )
  438.     {
  439.         cbFloatedBarWindow* pFFrm = ((cbFloatedBarWindow*)pNode->Data());
  440.  
  441.         pFFrm->Show( show );
  442.  
  443.         pNode = pNode->Next();
  444.     }
  445. }
  446.  
  447. wxFrameLayout::~wxFrameLayout()
  448. {
  449.     UnhookFromFrame();
  450.  
  451.     if ( mpUpdatesMgr )
  452.         delete mpUpdatesMgr;
  453.  
  454.     PopAllPlugins();
  455.  
  456.     // destoy the chain of plugins from left to right
  457.  
  458.     wxEvtHandler* pCur = mpTopPlugin;
  459.  
  460.     if ( pCur )
  461.  
  462.         while ( pCur->GetPreviousHandler() )
  463.  
  464.             pCur = pCur->GetPreviousHandler();
  465.  
  466.     while ( pCur )
  467.     {
  468.         wxEvtHandler* pNext = pCur->GetNextHandler();
  469.  
  470.         delete pCur;
  471.  
  472.         pCur = pNext;
  473.     }
  474.  
  475.     // destroy contents of arrays and lists
  476.  
  477.     size_t i = 0;
  478.     for ( i = 0; i != MAX_PANES; ++i )
  479.     {
  480.         if ( mPanes[i] ) 
  481.             delete mPanes[i];
  482.     }
  483.     if ( mpHorizCursor  ) 
  484.         delete mpHorizCursor;
  485.     if ( mpVertCursor   ) 
  486.         delete mpVertCursor;
  487.     if ( mpNormalCursor ) 
  488.         delete mpNormalCursor;
  489.     if ( mpDragCursor   ) 
  490.         delete mpDragCursor;
  491.     if ( mpNECursor     ) 
  492.         delete mpNECursor;
  493.  
  494.     wxNode* pSpy = mBarSpyList.First();
  495.  
  496.     while( pSpy )
  497.     {
  498.         cbBarSpy& spy = *((cbBarSpy*)pSpy->Data());
  499.  
  500.         if ( spy.mpBarWnd->GetEventHandler() == &spy )
  501.  
  502.             spy.mpBarWnd->PopEventHandler();
  503.  
  504.         delete &spy;
  505.  
  506.         pSpy = pSpy->Next();
  507.     }
  508.  
  509.     for ( i = 0; i != mAllBars.Count(); ++i )
  510.         delete mAllBars[i];
  511. }
  512.  
  513. void wxFrameLayout::EnableFloating( bool enable )
  514. {
  515.     mFloatingOn = enable && CanReparent();
  516. }
  517.  
  518. void wxFrameLayout::Activate()
  519. {
  520.     HookUpToFrame();
  521.  
  522.     RefreshNow( TRUE );
  523.  
  524.     ShowFloatedWindows( TRUE );
  525. }
  526.  
  527. void wxFrameLayout::Deactivate()
  528. {
  529.     ShowFloatedWindows( FALSE );
  530.  
  531.     UnhookFromFrame();
  532.  
  533.     HideBarWindows();
  534. }
  535.  
  536. void wxFrameLayout::SetFrameClient( wxWindow* pFrameClient )
  537. {
  538.     mpFrameClient = pFrameClient;
  539. }
  540.  
  541. wxWindow* wxFrameLayout::GetFrameClient()
  542. {
  543.     return mpFrameClient;
  544. }
  545.  
  546. cbUpdatesManagerBase& wxFrameLayout::GetUpdatesManager()
  547. {
  548.     if ( !mpUpdatesMgr )
  549.         mpUpdatesMgr = CreateUpdatesManager();
  550.  
  551.     return *mpUpdatesMgr;
  552. }
  553.  
  554. void wxFrameLayout::SetUpdatesManager( cbUpdatesManagerBase* pUMgr )
  555. {
  556.     if ( mpUpdatesMgr )
  557.         delete mpUpdatesMgr;
  558.  
  559.     mpUpdatesMgr = pUMgr;
  560.  
  561.     mpUpdatesMgr->SetLayout( this );
  562. }
  563.  
  564. cbUpdatesManagerBase* wxFrameLayout::CreateUpdatesManager()
  565. {
  566.     return new cbGCUpdatesMgr( this );
  567.     //return new cbSimpleUpdatesMgr( this );
  568. }
  569.  
  570. void wxFrameLayout::AddBar( wxWindow*        pBarWnd, 
  571.                             const cbDimInfo& dimInfo,
  572.                             int              alignment,
  573.                             int              rowNo,
  574.                             int              columnPos,
  575.                             const wxString&  name,
  576.                             bool             spyEvents,
  577.                             int              state
  578.                           )
  579. {
  580.     if ( pBarWnd && spyEvents )
  581.     {
  582.         // hook up spy to bar window
  583.         cbBarSpy* pSpy = new cbBarSpy( this );
  584.  
  585.         pSpy->SetBarWindow( pBarWnd );
  586.         pBarWnd->PushEventHandler( pSpy );
  587.  
  588.         mBarSpyList.Append( pSpy );
  589.     }
  590.  
  591.     cbBarInfo* pInfo = new cbBarInfo();
  592.  
  593.     pInfo->mName      = name;
  594.     pInfo->mpBarWnd   = pBarWnd;
  595.     pInfo->mDimInfo   = dimInfo;
  596.     pInfo->mState     = state;
  597.     pInfo->mAlignment = alignment;
  598.     pInfo->mRowNo     = rowNo;
  599.     pInfo->mBounds.x  = columnPos;
  600.  
  601.     mAllBars.Add( pInfo );
  602.  
  603.     DoSetBarState( pInfo );
  604. }
  605.  
  606. bool wxFrameLayout::RedockBar( cbBarInfo*    pBar, 
  607.                                const wxRect& shapeInParent,
  608.                                cbDockPane*   pToPane,
  609.                                bool          updateNow )
  610. {
  611.     if ( !pToPane )
  612.     
  613.         pToPane = HitTestPanes( shapeInParent, NULL );
  614.  
  615.     if ( !pToPane ) 
  616.         
  617.         return FALSE; // bar's shape does not hit any pane 
  618.                      // - redocking is NOT possible
  619.  
  620.     cbDockPane* pBarPane = GetBarPane( pBar );
  621.  
  622.     if ( updateNow )
  623.  
  624.         GetUpdatesManager().OnStartChanges();
  625.  
  626.     pBarPane->RemoveBar( pBar );
  627.  
  628.     // FIXME FIXME:: the recalculation below may be a *huge* performance
  629.     //               hit, it could be eliminated though...
  630.     //               but first the "pane-postion-changed" problem 
  631.     //               has to be fixed 
  632.  
  633.     RecalcLayout( FALSE );
  634.  
  635.     pToPane->InsertBar( pBar, shapeInParent );
  636.  
  637.     RecalcLayout( FALSE );
  638.  
  639.     // finish update "transaction"
  640.  
  641.     if ( updateNow )
  642.     {
  643.         GetUpdatesManager().OnFinishChanges();
  644.         GetUpdatesManager().UpdateNow();
  645.     }
  646.  
  647.     return TRUE;
  648. }
  649.  
  650. cbBarInfo* wxFrameLayout::FindBarByName( const wxString& name )
  651. {
  652.     size_t i;
  653.     for ( i = 0; i != mAllBars.Count(); ++i )
  654.         if ( mAllBars[i]->mName == name )
  655.             return mAllBars[i];
  656.  
  657.     return NULL;
  658. }
  659.  
  660. cbBarInfo* wxFrameLayout::FindBarByWindow( const wxWindow* pWnd )
  661. {
  662.     size_t i;
  663.     for ( i = 0; i != mAllBars.Count(); ++i )
  664.         if ( mAllBars[i]->mpBarWnd == pWnd )
  665.             return mAllBars[i];
  666.  
  667.     return NULL;
  668. }
  669.  
  670. BarArrayT& wxFrameLayout::GetBars()
  671. {
  672.     return mAllBars;
  673. }
  674.  
  675. void wxFrameLayout::SetBarState( cbBarInfo* pBar, int newState, bool updateNow )
  676. {
  677.     if ( newState == wxCBAR_FLOATING && !mFloatingOn )
  678.  
  679.         return;
  680.  
  681.     if ( updateNow )
  682.  
  683.         GetUpdatesManager().OnStartChanges();
  684.  
  685.     pBar->mUMgrData.SetDirty(TRUE);
  686.  
  687.     // check bar's previous state
  688.  
  689.     if ( pBar->mState != wxCBAR_HIDDEN && pBar->mState != wxCBAR_FLOATING )
  690.     {
  691.         cbDockPane* pPane;
  692.         cbRowInfo*  pRow;
  693.  
  694.         bool success = LocateBar( pBar, &pRow, &pPane );
  695.  
  696.         wxASSERT( success ); // DBG::
  697.  
  698.         // save LRU-dim info before removing bar
  699.  
  700.         pBar->mDimInfo.mLRUPane = pPane->GetAlignment();
  701.         pBar->mDimInfo.mBounds[ pPane->GetAlignment() ] = pBar->mBounds;
  702.  
  703.         // remove it from the pane it was docked on
  704.  
  705.         pPane->RemoveBar( pBar );
  706.  
  707.     }
  708.  
  709.     if ( pBar->mState == wxCBAR_FLOATING && newState != wxCBAR_FLOATING )
  710.     {
  711.         // remove bar's window from the containing mini-frame
  712.         // and set its parent to be layout's parent frame
  713.  
  714.         if ( pBar->mpBarWnd )
  715.         {
  716.             pBar->mpBarWnd->Show(FALSE); // to avoid flicker upon reparenting
  717.  
  718.             wxNode* pNode = mFloatedFrames.First();
  719.  
  720.             while( pNode )
  721.             {
  722.                 cbFloatedBarWindow* pFFrm = ((cbFloatedBarWindow*)pNode->Data());
  723.  
  724.                 if ( pFFrm->GetBar() == pBar )
  725.                 {
  726.                     pFFrm->Show( FALSE ); // reduces flicker sligthly 
  727.  
  728.                     ReparentWindow( pBar->mpBarWnd, &GetParentFrame() );
  729.  
  730.                     pBar->mBounds = pBar->mDimInfo.mBounds[ pBar->mDimInfo.mLRUPane ];
  731.  
  732.                     if ( newState != wxCBAR_HIDDEN )
  733.  
  734.                         pBar->mAlignment = pBar->mDimInfo.mLRUPane;
  735.  
  736.                     mFloatedFrames.DeleteNode( pNode );
  737.  
  738.                     pFFrm->Show( FALSE );
  739.                     pFFrm->Destroy(); break;
  740.                 }
  741.  
  742.                 pNode = pNode->Next();
  743.             }
  744.  
  745.             // FOR NOW:: excessive!
  746.             //if ( mpFrameClient ) mpFrameClient->Refresh();
  747.             if ( mpFrameClient )
  748.                 mClientWndRefreshPending = TRUE;
  749.         }
  750.     }
  751.  
  752.     if ( pBar->mDimInfo.GetDimHandler() )
  753.     {
  754.         pBar->mDimInfo.GetDimHandler()->OnChangeBarState( pBar, newState );
  755.     }
  756.  
  757.     pBar->mState = newState;
  758.  
  759.     DoSetBarState( pBar );
  760.  
  761.     if ( updateNow )
  762.     {
  763.         RecalcLayout(FALSE);
  764.  
  765.         GetUpdatesManager().OnFinishChanges();
  766.         GetUpdatesManager().UpdateNow();
  767.     }
  768. }
  769.  
  770. void wxFrameLayout::InverseVisibility( cbBarInfo* pBar )
  771. {
  772.     wxASSERT( pBar ); // DBG::
  773.  
  774.     // "inverse" bar-visibility of the selected bar
  775.  
  776.     int newState = 0;
  777.  
  778.     if ( pBar->mState == wxCBAR_HIDDEN )
  779.     {
  780.         if ( pBar->mAlignment == -1 )
  781.         {
  782.             pBar->mAlignment = 0;       // just remove "-1" marking
  783.             newState = wxCBAR_FLOATING;
  784.         }
  785.         else
  786.         if ( pBar->mAlignment == FL_ALIGN_TOP ||
  787.              pBar->mAlignment == FL_ALIGN_BOTTOM )
  788.  
  789.             newState = wxCBAR_DOCKED_HORIZONTALLY;
  790.         else
  791.             newState = wxCBAR_DOCKED_VERTICALLY;
  792.     }
  793.     else
  794.     {
  795.         newState = wxCBAR_HIDDEN;
  796.  
  797.         if ( pBar->mState == wxCBAR_FLOATING )
  798.  
  799.             pBar->mAlignment = -1;
  800.     }
  801.  
  802.     this->SetBarState( pBar, newState, TRUE );
  803.  
  804.     if ( newState == wxCBAR_FLOATING )
  805.  
  806.         this->RepositionFloatedBar( pBar ); 
  807. }
  808.  
  809. void wxFrameLayout::ApplyBarProperties( cbBarInfo* pBar )
  810. {
  811.     if ( pBar->mState == wxCBAR_FLOATING )
  812.     {
  813.         RepositionFloatedBar( pBar );
  814.     }
  815.     else
  816.     if ( pBar->mState == wxCBAR_DOCKED_HORIZONTALLY ||
  817.          pBar->mState == wxCBAR_DOCKED_VERTICALLY
  818.        )
  819.     {
  820.         // FOR NOW:: nothing
  821.     }
  822.  
  823. }
  824.  
  825. void wxFrameLayout::RepositionFloatedBar( cbBarInfo* pBar )
  826. {
  827.     if ( !mFloatingOn ) return;
  828.  
  829.     wxNode* pNode = mFloatedFrames.First();
  830.  
  831.     while( pNode )
  832.     {
  833.         cbFloatedBarWindow* pFFrm = ((cbFloatedBarWindow*)pNode->Data());
  834.  
  835.         if ( pFFrm->GetBar() == pBar )
  836.         {
  837.             wxRect& bounds = pBar->mDimInfo.mBounds[wxCBAR_FLOATING];
  838.  
  839.             int x = bounds.x,
  840.                 y = bounds.y;
  841.  
  842.             GetParentFrame().ClientToScreen( &x, &y );
  843.  
  844.             pFFrm->PositionFloatedWnd( x,y, 
  845.                                        bounds.width,
  846.                                        bounds.height );
  847.  
  848.             break;
  849.         }
  850.  
  851.         pNode = pNode->Next();
  852.     }
  853. }
  854.  
  855. void wxFrameLayout::DoSetBarState( cbBarInfo* pBar )
  856. {
  857.     if ( pBar->mState != wxCBAR_FLOATING &&
  858.          pBar->mState != wxCBAR_HIDDEN )
  859.     
  860.         // dock it
  861.  
  862.         mPanes[pBar->mAlignment]->InsertBar( pBar );
  863.     else
  864.     if ( pBar->mState == wxCBAR_HIDDEN )
  865.     {
  866.         // hide it
  867.  
  868.         if ( pBar->mpBarWnd )
  869.  
  870.             pBar->mpBarWnd->Show( FALSE );
  871.     }
  872.     else
  873.     {                   
  874.         if ( !mFloatingOn ) return;
  875.  
  876.         // float it
  877.  
  878.         if ( pBar->mpBarWnd == NULL || !CanReparent() )
  879.         {                               
  880.             // FOR NOW:: just hide it
  881.  
  882.             if ( pBar->mpBarWnd )
  883.  
  884.                 pBar->mpBarWnd->Show( FALSE );
  885.  
  886.             pBar->mState = wxCBAR_HIDDEN;
  887.  
  888.             return;
  889.         }
  890.  
  891.         cbFloatedBarWindow* pMiniFrm = new cbFloatedBarWindow();
  892.  
  893.         pMiniFrm->SetBar( pBar );
  894.         pMiniFrm->SetLayout( this );
  895.  
  896.         pMiniFrm->Create( &GetParentFrame(), -1, pBar->mName, 
  897.                           wxPoint( 50,50 ),
  898.                           wxSize ( 0, 0  ),
  899.                           wxFRAME_FLOAT_ON_PARENT |
  900.                           wxFRAME_TOOL_WINDOW |
  901.                           wxFRAME_NO_TASKBAR
  902.                         );
  903.  
  904.         pMiniFrm->SetClient( pBar->mpBarWnd );
  905.  
  906.         ReparentWindow( pBar->mpBarWnd, pMiniFrm );
  907.  
  908.         mFloatedFrames.Append( pMiniFrm );
  909.  
  910.         wxRect& bounds = pBar->mDimInfo.mBounds[wxCBAR_FLOATING];
  911.  
  912.         // check if it wasn't floated anytime before
  913.  
  914.         if ( bounds.width == -1 )
  915.         {
  916.             wxRect& clntRect = GetClientRect();
  917.  
  918.             // adjust position into which the next floated bar will be placed
  919.  
  920.             if ( mNextFloatedWndPos.x + bounds.width > clntRect.width )
  921.  
  922.                 mNextFloatedWndPos.x = mFloatingPosStep.x;
  923.  
  924.             if ( mNextFloatedWndPos.y + bounds.height > clntRect.height )
  925.  
  926.                 mNextFloatedWndPos.y = mFloatingPosStep.y;
  927.  
  928.             bounds.x = mNextFloatedWndPos.x + clntRect.x;
  929.             bounds.y = mNextFloatedWndPos.y + clntRect.y;
  930.  
  931.             bounds.width  = pBar->mDimInfo.mSizes[wxCBAR_FLOATING].x;
  932.             bounds.height = pBar->mDimInfo.mSizes[wxCBAR_FLOATING].y;
  933.  
  934.             mNextFloatedWndPos.x += mFloatingPosStep.x;
  935.             mNextFloatedWndPos.y += mFloatingPosStep.y;
  936.         }
  937.  
  938.         pMiniFrm->Show( TRUE );
  939.  
  940.         // FIXME:: this is excessive
  941.         pBar->mpBarWnd->Show(TRUE);
  942.     }
  943. }
  944.  
  945. void wxFrameLayout::RemoveBar( cbBarInfo* pBarInfo )
  946. {
  947.     // first, try to "guess" what was the perviouse state of the bar
  948.  
  949.     cbDockPane* pPane;
  950.     cbRowInfo*  pRow;
  951.  
  952.     if ( LocateBar( pBarInfo, &pRow, &pPane ) )
  953.     {
  954.         // ...aha, bar was docked into one of the panes,
  955.         // remove it from there
  956.  
  957.         pPane->RemoveBar( pBarInfo );
  958.     }
  959.  
  960.     size_t i;
  961.     for ( i = 0; i != mAllBars.Count(); ++i )
  962.     {
  963.         if ( mAllBars[i] == pBarInfo )
  964.         {
  965. #if wxCHECK_VERSION(2,3,2)
  966.             mAllBars.RemoveAt(i); 
  967. #else
  968.             mAllBars.Remove(i); 
  969. #endif
  970.             if ( pBarInfo->mpBarWnd ) // hides it's window
  971.  
  972.                 pBarInfo->mpBarWnd->Show( FALSE );
  973.  
  974.             delete pBarInfo;
  975.  
  976.             return;
  977.         }
  978.     }
  979.     wxFAIL_MSG("bar info should be present in the list of all bars of all panes");
  980. }
  981.  
  982. bool wxFrameLayout::LocateBar( cbBarInfo* pBarInfo, 
  983.                                cbRowInfo**  ppRow,
  984.                                cbDockPane** ppPane )
  985. {
  986.     (*ppRow)  = NULL;
  987.     (*ppPane) = NULL;
  988.  
  989.     int n;
  990.     for ( n = 0; n != MAX_PANES; ++n )
  991.     {
  992.         wxBarIterator i( mPanes[n]->GetRowList() );
  993.  
  994.         while ( i.Next() )
  995.         
  996.             if ( &i.BarInfo() == pBarInfo )
  997.             {
  998.                 (*ppPane) = mPanes[n];
  999.                 (*ppRow ) = &i.RowInfo();
  1000.  
  1001.                 return TRUE;
  1002.             }
  1003.     }
  1004.  
  1005.     return FALSE;
  1006. }
  1007.  
  1008. void wxFrameLayout::RecalcLayout( bool repositionBarsNow )
  1009. {
  1010.     mRecalcPending = FALSE;
  1011.  
  1012.     int frmWidth, frmHeight;
  1013.     mpFrame->GetClientSize( &frmWidth, &frmHeight );
  1014.     int paneHeight = 0;
  1015.  
  1016.     int curY = 0;
  1017.     int curX = 0;
  1018.     wxRect rect;
  1019.  
  1020.     // pane positioning priorities in decreasing order:
  1021.     // top, bottom, left, right
  1022.  
  1023.     // setup TOP pane
  1024.  
  1025.     cbDockPane* pPane = mPanes[ FL_ALIGN_TOP ];
  1026.  
  1027.     pPane->SetPaneWidth( frmWidth );
  1028.     pPane->RecalcLayout();
  1029.  
  1030.     paneHeight = pPane->GetPaneHeight();
  1031.  
  1032.     rect.x      = curX;
  1033.     rect.y      = curY;
  1034.     rect.width  = frmWidth;
  1035.     rect.height = wxMin( paneHeight, frmHeight - curY );
  1036.  
  1037.     pPane->SetBoundsInParent( rect );
  1038.  
  1039.     curY += paneHeight;
  1040.  
  1041.     // setup BOTTOM pane
  1042.  
  1043.     pPane = mPanes[ FL_ALIGN_BOTTOM ];
  1044.  
  1045.     pPane->SetPaneWidth( frmWidth );
  1046.     pPane->RecalcLayout();
  1047.  
  1048.     paneHeight = pPane->GetPaneHeight();
  1049.  
  1050.     rect.x      = curX;
  1051.     rect.y      = wxMax( frmHeight - paneHeight, curY );
  1052.     rect.width  = frmWidth;
  1053.     rect.height = frmHeight - rect.y;
  1054.  
  1055.     pPane->SetBoundsInParent( rect );
  1056.  
  1057.     // setup LEFT pane 
  1058.  
  1059.     pPane = mPanes[ FL_ALIGN_LEFT ];
  1060.  
  1061.                          // bottom pane's y
  1062.     pPane->SetPaneWidth( rect.y - curY );
  1063.  
  1064.     pPane->RecalcLayout();
  1065.     paneHeight = pPane->GetPaneHeight();
  1066.  
  1067.                   // bottom rect's y
  1068.     rect.height = rect.y - curY;
  1069.     rect.x = curX;
  1070.     rect.y = curY;
  1071.     rect.width  = wxMin( paneHeight, frmWidth );
  1072.  
  1073.     pPane->SetBoundsInParent( rect );
  1074.  
  1075.     curX += rect.width;
  1076.  
  1077.     // setup RIGHT pane
  1078.  
  1079.     pPane = mPanes[ FL_ALIGN_RIGHT ];
  1080.  
  1081.                          // left pane's height
  1082.     pPane->SetPaneWidth( rect.height );
  1083.  
  1084.     pPane->RecalcLayout();
  1085.     paneHeight = pPane->GetPaneHeight();
  1086.  
  1087.                   // left pane's height
  1088.     rect.height = rect.height;
  1089.     rect.x = wxMax( frmWidth - paneHeight, curX );
  1090.     rect.y = curY;
  1091.     rect.width  = frmWidth - rect.x;
  1092.  
  1093.     pPane->SetBoundsInParent( rect );
  1094.  
  1095.     // recalc bounds of the client-window
  1096.  
  1097.     mClntWndBounds.x = mPanes[FL_ALIGN_LEFT]->mBoundsInParent.x + 
  1098.                        mPanes[FL_ALIGN_LEFT]->mBoundsInParent.width;
  1099.     mClntWndBounds.y = mPanes[FL_ALIGN_TOP ]->mBoundsInParent.y + 
  1100.                        mPanes[FL_ALIGN_TOP ]->mBoundsInParent.height;
  1101.  
  1102.     mClntWndBounds.width  = mPanes[FL_ALIGN_RIGHT]->mBoundsInParent.x -
  1103.                             mClntWndBounds.x;
  1104.     mClntWndBounds.height = mPanes[FL_ALIGN_BOTTOM]->mBoundsInParent.y -
  1105.                             mClntWndBounds.y;
  1106.  
  1107.     if ( repositionBarsNow )
  1108.  
  1109.         PositionPanes();
  1110. }
  1111.  
  1112. int wxFrameLayout::GetClientHeight()
  1113. {
  1114.     // for better portablility wxWindow::GetSzie() is not used here
  1115.  
  1116.     return mClntWndBounds.height;
  1117. }
  1118.  
  1119. int wxFrameLayout::GetClientWidth()
  1120. {
  1121.     // for better portablility wxWindow::GetSzie() is not used here
  1122.  
  1123.     return mClntWndBounds.width;
  1124. }
  1125.  
  1126. void wxFrameLayout::PositionClientWindow()
  1127. {
  1128.     if ( mpFrameClient )
  1129.     {
  1130.         if ( mClntWndBounds.width >= 1 && mClntWndBounds.height >= 1 )
  1131.         {
  1132.             mpFrameClient->SetSize( mClntWndBounds.x,     mClntWndBounds.y, 
  1133.                                     mClntWndBounds.width, mClntWndBounds.height, 0 );
  1134.  
  1135.             if ( !mpFrameClient->IsShown() )
  1136.  
  1137.                 mpFrameClient->Show( TRUE );
  1138.         }
  1139.         else
  1140.             mpFrameClient->Show( FALSE );
  1141.     }
  1142. }
  1143.  
  1144. void wxFrameLayout::PositionPanes()
  1145. {
  1146.     PositionClientWindow();
  1147.  
  1148.     // FOR NOW:: excessive updates!
  1149.     // reposition bars within all panes
  1150.  
  1151.     int i;
  1152.     for ( i = 0; i != MAX_PANES; ++i )
  1153.         mPanes[i]->SizePaneObjects();
  1154. }
  1155.  
  1156. void wxFrameLayout::OnSize( wxSizeEvent& event )
  1157. {
  1158.     mpFrame->ProcessEvent( event );
  1159.     event.Skip( FALSE ); // stop its progpagation
  1160.  
  1161.     if ( event.GetEventObject() == (wxObject*) mpFrame )
  1162.     {
  1163.         GetUpdatesManager().OnStartChanges();
  1164.         RecalcLayout(TRUE);
  1165.         GetUpdatesManager().OnFinishChanges();
  1166.         GetUpdatesManager().UpdateNow();
  1167.     }
  1168.  
  1169. }
  1170.  
  1171. /*** protected members ***/
  1172.  
  1173. void wxFrameLayout::HideBarWindows()
  1174. {
  1175.     size_t i;
  1176.     for ( i = 0; i != mAllBars.Count(); ++i )
  1177.         if ( mAllBars[i]->mpBarWnd && mAllBars[i]->mState != wxCBAR_FLOATING )
  1178.             mAllBars[i]->mpBarWnd->Show( FALSE );
  1179.  
  1180.     // then floated frames
  1181.  
  1182.     ShowFloatedWindows( FALSE );
  1183.  
  1184.     if ( mpFrameClient )
  1185.  
  1186.         mpFrameClient->Show( FALSE );
  1187. }
  1188.  
  1189. void wxFrameLayout::UnhookFromFrame()
  1190. {
  1191.     // NOTE:: the SetEvtHandlerEnabled() method is not used
  1192.     //        here, since it is assumed that unhooking layout
  1193.     //        from window may result destroying of the layout itself
  1194.     //       
  1195.     //        BUG BUG BUG (wx):: this would not be a problem if 
  1196.     //                           wxEvtHandler's destructor checked if 
  1197.     //                           this handler is currently the top-most 
  1198.     //                           handler of some window, and additionally 
  1199.     //                           to the reconnecting itself from the chain.
  1200.     //                           It would also re-setup current event handler 
  1201.     //                           of the window using wxWindow::SetEventHandler()
  1202.  
  1203.     // FOR NOW::
  1204.  
  1205.     if ( mpFrame->GetEventHandler() == this )
  1206.     {
  1207.         mpFrame->PopEventHandler();
  1208.         return;
  1209.     }
  1210.  
  1211.     if ( mpFrame )
  1212.     {
  1213.         if ( this == mpFrame->GetEventHandler() )
  1214.         {
  1215.             mpFrame->SetEventHandler( this->GetNextHandler() );
  1216.         }
  1217.         else
  1218.         {
  1219.             wxEvtHandler* pCur = mpFrame->GetEventHandler();
  1220.  
  1221.             while ( pCur )
  1222.             {
  1223.                 if ( pCur == this )
  1224.                     break;
  1225.  
  1226.                 pCur = pCur->GetNextHandler();
  1227.             }
  1228.  
  1229.             // do not try to unhook ourselves if we're not hooked yet
  1230.             if ( !pCur )
  1231.                 return;
  1232.         }
  1233.  
  1234.         if ( GetPreviousHandler() )
  1235.             GetPreviousHandler()->SetNextHandler( GetNextHandler() );
  1236.         else
  1237.         {
  1238.             mpFrame->PopEventHandler();
  1239.             return;
  1240.         }
  1241.  
  1242.         if ( GetNextHandler() )
  1243.             GetNextHandler()->SetPreviousHandler( GetPreviousHandler() );
  1244.  
  1245.         SetNextHandler( NULL );
  1246.         SetPreviousHandler( NULL );
  1247.     }
  1248. }
  1249.  
  1250. void wxFrameLayout::HookUpToFrame()
  1251. {
  1252.     // unhook us first, we're already hooked up
  1253.  
  1254.     UnhookFromFrame();
  1255.  
  1256.     // put ourselves on top
  1257.  
  1258.     mpFrame->PushEventHandler( this );
  1259. }
  1260.  
  1261. cbDockPane* wxFrameLayout::GetBarPane( cbBarInfo* pBar )
  1262. {
  1263.     int i;
  1264.     for ( i = 0; i != MAX_PANES; ++i )
  1265.         if ( mPanes[i]->BarPresent( pBar ) )
  1266.             return mPanes[i];
  1267.  
  1268.     return NULL;
  1269. }
  1270.  
  1271. void wxFrameLayout::CreateCursors()
  1272. {
  1273.     /*
  1274.     // FIXME:: The below code somehow doesn't work - cursors remain unchanged
  1275.     char bits[64];
  1276.     
  1277.     set_cursor_bits( _gHorizCursorImg, bits, 32, 16 );
  1278.  
  1279.     mpHorizCursor = new wxCursor( bits, 32, 16 );
  1280.  
  1281.     set_cursor_bits( _gVertCursorImg, bits, 32, 16 );
  1282.  
  1283.     mpVertCursor  = new wxCursor( bits, 32, 16 );
  1284.     */
  1285.  
  1286.     // FOR NOW:: use standard ones
  1287.  
  1288.     mpHorizCursor  = new wxCursor(wxCURSOR_SIZEWE);
  1289.     mpVertCursor   = new wxCursor(wxCURSOR_SIZENS);
  1290.     mpNormalCursor = new wxCursor(wxCURSOR_ARROW );
  1291.     mpDragCursor   = new wxCursor(wxCURSOR_CROSS );
  1292.     mpNECursor     = new wxCursor(wxCURSOR_NO_ENTRY);
  1293.  
  1294.     mFloatingPosStep.x = 25;
  1295.     mFloatingPosStep.y = 25;
  1296.  
  1297.     mNextFloatedWndPos.x = mFloatingPosStep.x;
  1298.     mNextFloatedWndPos.y = mFloatingPosStep.y;
  1299. }
  1300.  
  1301. bool wxFrameLayout::HitTestPane( cbDockPane* pPane, int x, int y )
  1302. {
  1303.     return rect_contains_point( pPane->GetRealRect(), x, y );
  1304. }
  1305.  
  1306. cbDockPane* wxFrameLayout::HitTestPanes( const wxRect& rect,
  1307.                                          cbDockPane* pCurPane )
  1308. {
  1309.     // first, give the privilege to the current pane
  1310.  
  1311.     if ( pCurPane && rect_hits_rect( pCurPane->GetRealRect(), rect ) ) 
  1312.     
  1313.         return pCurPane;
  1314.  
  1315.     int i;
  1316.     for ( i = 0; i != MAX_PANES; ++i )
  1317.     {
  1318.         if ( pCurPane != mPanes[i] &&
  1319.              rect_hits_rect( mPanes[i]->GetRealRect(), rect ) ) 
  1320.         {
  1321.             return mPanes[i];
  1322.         }
  1323.     }
  1324.     return 0;
  1325. }
  1326.  
  1327. void wxFrameLayout::ForwardMouseEvent( wxMouseEvent& event, 
  1328.                                            cbDockPane*   pToPane,
  1329.                                            int           eventType )
  1330. {
  1331.     wxPoint pos( event.m_x, event.m_y );
  1332.     pToPane->FrameToPane( &pos.x, &pos.y );
  1333.  
  1334.     if ( eventType == cbEVT_PL_LEFT_DOWN )
  1335.     {
  1336.         cbLeftDownEvent evt( pos, pToPane );
  1337.         FirePluginEvent( evt );
  1338.     }
  1339.     else if ( eventType == cbEVT_PL_LEFT_DCLICK )
  1340.     {
  1341.         cbLeftDClickEvent evt( pos, pToPane );
  1342.         FirePluginEvent( evt );
  1343.     }
  1344.     else if ( eventType == cbEVT_PL_LEFT_UP )
  1345.     {
  1346.         cbLeftUpEvent evt( pos, pToPane );
  1347.         FirePluginEvent( evt );
  1348.     }
  1349.     else if ( eventType == cbEVT_PL_RIGHT_DOWN )
  1350.     {
  1351.         cbRightDownEvent evt( pos, pToPane );
  1352.         FirePluginEvent( evt );
  1353.     }
  1354.     else if ( eventType == cbEVT_PL_RIGHT_UP )
  1355.     {
  1356.         cbRightUpEvent evt( pos, pToPane );
  1357.         FirePluginEvent( evt );
  1358.     }
  1359.     else if ( eventType == cbEVT_PL_MOTION )
  1360.     {
  1361.         cbMotionEvent evt( pos, pToPane );
  1362.         FirePluginEvent( evt );
  1363.     }
  1364.     else 
  1365.     {
  1366.         int avoidCompilerWarning = 0;
  1367.         wxASSERT(avoidCompilerWarning); // DBG::
  1368.     }
  1369. }  // wxFrameLayout::ForwardMouseEvent()
  1370.  
  1371.  
  1372. void wxFrameLayout::RouteMouseEvent( wxMouseEvent& event, int pluginEvtType )
  1373. {
  1374.     if ( mpPaneInFocus )
  1375.  
  1376.         ForwardMouseEvent( event, mpPaneInFocus, pluginEvtType );
  1377.     else
  1378.     {
  1379.         int i;
  1380.         for ( i = 0; i != MAX_PANES; ++i )
  1381.         {
  1382.             if ( HitTestPane( mPanes[i], event.m_x, event.m_y ) )
  1383.             {
  1384.                 ForwardMouseEvent( event, mPanes[i], pluginEvtType );
  1385.                 return;
  1386.             }
  1387.         }
  1388.     }
  1389. }
  1390.  
  1391. /*** event handlers ***/
  1392.  
  1393. void wxFrameLayout::OnRButtonDown( wxMouseEvent& event )
  1394. {
  1395.     RouteMouseEvent( event, cbEVT_PL_RIGHT_DOWN );
  1396. }
  1397.  
  1398. void wxFrameLayout::OnRButtonUp( wxMouseEvent& event )
  1399. {
  1400.     RouteMouseEvent( event, cbEVT_PL_RIGHT_UP );
  1401. }
  1402.  
  1403. void wxFrameLayout::OnLButtonDown( wxMouseEvent& event )
  1404. {
  1405.     RouteMouseEvent( event, cbEVT_PL_LEFT_DOWN );
  1406. }
  1407.  
  1408. void wxFrameLayout::OnLDblClick( wxMouseEvent& event )
  1409. {
  1410.     RouteMouseEvent( event, cbEVT_PL_LEFT_DCLICK );
  1411. }
  1412.  
  1413. void wxFrameLayout::OnLButtonUp( wxMouseEvent& event )
  1414. {
  1415.     RouteMouseEvent( event, cbEVT_PL_LEFT_UP );
  1416. }
  1417.  
  1418. void wxFrameLayout::OnMouseMove( wxMouseEvent& event )
  1419. {
  1420.     if ( mpPaneInFocus )
  1421.     
  1422.         ForwardMouseEvent( event, mpPaneInFocus, cbEVT_PL_MOTION );
  1423.     else
  1424.     {
  1425.         int i;
  1426.         for ( i = 0; i != MAX_PANES; ++i )
  1427.         {
  1428.             if ( HitTestPane( mPanes[i], event.m_x, event.m_y ) )
  1429.             {
  1430.                 if ( mpLRUPane && mpLRUPane != mPanes[i] )
  1431.                 {
  1432.                     // simulate "mouse-leave" event
  1433.                     ForwardMouseEvent( event, mpLRUPane, cbEVT_PL_MOTION );
  1434.                 }
  1435.  
  1436.                 ForwardMouseEvent( event, mPanes[i], cbEVT_PL_MOTION );
  1437.  
  1438.                 mpLRUPane = mPanes[i];
  1439.  
  1440.                 return;
  1441.             }
  1442.         }
  1443.     }
  1444.  
  1445.     if ( mpLRUPane )
  1446.     {
  1447.         // simulate "mouse-leave" event
  1448.         ForwardMouseEvent( event, mpLRUPane, cbEVT_PL_MOTION );
  1449.         mpLRUPane = 0;
  1450.     }
  1451. }
  1452.  
  1453. void wxFrameLayout::OnPaint( wxPaintEvent& event )
  1454. {
  1455.     if ( mRecalcPending  )
  1456.         RecalcLayout( TRUE );
  1457.  
  1458.     wxPaintDC dc(mpFrame);
  1459.  
  1460.     int i;
  1461.     for ( i = 0; i != MAX_PANES; ++i )
  1462.     {
  1463.         wxRect& rect = mPanes[i]->mBoundsInParent;
  1464.  
  1465.         dc.SetClippingRegion( rect.x, rect.y, rect.width, rect.height );
  1466.  
  1467.         mPanes[i]->PaintPane(dc);
  1468.  
  1469.         dc.DestroyClippingRegion();
  1470.     }
  1471.  
  1472.     event.Skip();
  1473. }
  1474.  
  1475. void wxFrameLayout::OnEraseBackground( wxEraseEvent& event )
  1476. {
  1477.     // do nothing
  1478. }
  1479.  
  1480. void wxFrameLayout::OnIdle( wxIdleEvent& event )
  1481. {
  1482.     wxWindow* focus = wxWindow::FindFocus();
  1483.  
  1484.     if ( !focus && mCheckFocusWhenIdle )
  1485.     {
  1486.         wxMessageBox( "Hi, no more focus in this app!" );
  1487.  
  1488.         mCheckFocusWhenIdle = FALSE;
  1489.         //ShowFloatedWindows( FALSE );
  1490.     }
  1491.  
  1492.     mCheckFocusWhenIdle = FALSE;
  1493.  
  1494.     event.Skip();
  1495. }
  1496.  
  1497.  
  1498. void wxFrameLayout::OnKillFocus( wxFocusEvent& event )
  1499. {
  1500.     //wxMessageBox( "wxFrameLayoutGot Kill Focus!" );
  1501.     //ShowFloatedWindows( FALSE );
  1502. }
  1503.  
  1504. void wxFrameLayout::OnSetFocus( wxFocusEvent& event )
  1505. {
  1506.     //ShowFloatedWindows( TRUE );
  1507. }
  1508.  
  1509. void wxFrameLayout::OnActivate( wxActivateEvent& event )
  1510. {
  1511. #if 0
  1512.     if ( event.GetActive() == FALSE )               
  1513.     {
  1514.         wxWindow* focus = wxWindow::FindFocus();
  1515.  
  1516.         if ( !focus || focus == &GetParentFrame() )
  1517.         {
  1518.             mCheckFocusWhenIdle = TRUE;
  1519.  
  1520.             if ( !focus )
  1521.  
  1522.                 wxMessageBox("Deactivated!" );
  1523.  
  1524.         }
  1525.     }
  1526. #endif
  1527. }
  1528.  
  1529. void wxFrameLayout::GetPaneProperties( cbCommonPaneProperties& props, int alignment )
  1530. {
  1531.     props = mPanes[alignment]->mProps;
  1532. }
  1533.  
  1534. void wxFrameLayout::SetPaneProperties( const cbCommonPaneProperties& props, int paneMask )
  1535. {
  1536.     int i;
  1537.     for ( i = 0; i != MAX_PANES; ++i )
  1538.     {
  1539.         if ( mPanes[i]->MatchesMask( paneMask ) )
  1540.             mPanes[i]->mProps = props;
  1541.     }
  1542. }
  1543.  
  1544. void wxFrameLayout::SetMargins( int top, int bottom, int left, int right,
  1545.                                 int paneMask )
  1546. {
  1547.     int i;
  1548.     for ( i = 0; i != MAX_PANES; ++i )
  1549.     {
  1550.         cbDockPane& pane = *mPanes[i];
  1551.  
  1552.         if ( pane.MatchesMask( paneMask ) )
  1553.         {
  1554.             pane.mTopMargin = top;
  1555.             pane.mBottomMargin = bottom;
  1556.             pane.mLeftMargin = left;
  1557.             pane.mRightMargin = right;
  1558.         }
  1559.     }
  1560. }
  1561.  
  1562. void wxFrameLayout::SetPaneBackground( const wxColour& colour )
  1563. {
  1564.     mBorderPen.SetColour( colour );
  1565. }
  1566.  
  1567. void wxFrameLayout::RefreshNow( bool recalcLayout )
  1568. {
  1569.     if ( recalcLayout )
  1570.         RecalcLayout( TRUE );
  1571.  
  1572.     if ( mpFrame )
  1573.         mpFrame->Refresh();
  1574. }
  1575.  
  1576. /*** plugin-related methods ***/
  1577.  
  1578. void wxFrameLayout::FirePluginEvent( cbPluginEvent& event )
  1579. {
  1580.     // check state of input capture, before processing the event
  1581.  
  1582.     if ( mpCaputesInput ) 
  1583.     {
  1584.         bool isInputEvt = TRUE;
  1585. #if wxCHECK_VERSION(2,3,0)
  1586.         if ( event.m_eventType != cbEVT_PL_LEFT_DOWN &&
  1587.              event.m_eventType != cbEVT_PL_LEFT_UP &&
  1588.              event.m_eventType != cbEVT_PL_RIGHT_DOWN &&
  1589.              event.m_eventType != cbEVT_PL_RIGHT_UP &&
  1590.              event.m_eventType != cbEVT_PL_MOTION )
  1591.             isInputEvt = FALSE;
  1592. #else
  1593.         switch ( event.m_eventType )
  1594.         {
  1595.             case cbEVT_PL_LEFT_DOWN  : break;
  1596.             case cbEVT_PL_LEFT_UP    : break;
  1597.             case cbEVT_PL_RIGHT_DOWN : break;
  1598.             case cbEVT_PL_RIGHT_UP   : break;
  1599.             case cbEVT_PL_MOTION     : break;
  1600.             
  1601.             default : isInputEvt = FALSE; break;
  1602.         }
  1603. #endif  // #if wxCHECK_VERSION(2,3,0)
  1604.  
  1605.         if ( isInputEvt )
  1606.         {
  1607.             mpCaputesInput->ProcessEvent( event );
  1608.             return;
  1609.         }
  1610.     }
  1611.  
  1612.     GetTopPlugin().ProcessEvent( event );
  1613. }
  1614.  
  1615. void wxFrameLayout::CaptureEventsForPlugin ( cbPluginBase* pPlugin )
  1616. {
  1617.     // cannot capture events for more than one plugin at a time
  1618.     wxASSERT( mpCaputesInput == NULL );
  1619.  
  1620.     mpCaputesInput = pPlugin;
  1621.  
  1622. }
  1623.  
  1624. void wxFrameLayout::ReleaseEventsFromPlugin( cbPluginBase* pPlugin )
  1625. {
  1626.     // events should be captured first
  1627.     wxASSERT( mpCaputesInput != NULL );
  1628.  
  1629.     mpCaputesInput = NULL;
  1630. }
  1631.  
  1632. void wxFrameLayout::CaptureEventsForPane( cbDockPane* toPane )
  1633. {
  1634.     // cannot capture events twice (without releasing)
  1635.     wxASSERT( mpPaneInFocus == NULL );
  1636.  
  1637.     mpFrame->CaptureMouse();
  1638.  
  1639.     mpPaneInFocus = toPane;
  1640. }
  1641.  
  1642. void wxFrameLayout::ReleaseEventsFromPane( cbDockPane* fromPane )
  1643. {
  1644.     // cannot release events without capturing them
  1645.     wxASSERT( mpPaneInFocus != NULL );
  1646.  
  1647.     mpFrame->ReleaseMouse();
  1648.  
  1649.     mpPaneInFocus = NULL;
  1650. }
  1651.  
  1652. cbPluginBase& wxFrameLayout::GetTopPlugin()
  1653. {
  1654.     if ( !mpTopPlugin ) 
  1655.     
  1656.         PushDefaultPlugins(); // automatic configuration
  1657.  
  1658.     return *mpTopPlugin;
  1659. }
  1660.  
  1661. void wxFrameLayout::SetTopPlugin( cbPluginBase* pPlugin ) 
  1662.     mpTopPlugin = pPlugin; 
  1663. }
  1664.  
  1665. bool wxFrameLayout::HasTopPlugin() 
  1666.     return ( mpTopPlugin != NULL ); 
  1667. }
  1668.  
  1669. void wxFrameLayout::PushPlugin( cbPluginBase* pPlugin )
  1670. {
  1671.     if ( !mpTopPlugin ) 
  1672.         
  1673.         mpTopPlugin = pPlugin;
  1674.     else
  1675.     {
  1676.         pPlugin->SetNextHandler( mpTopPlugin );
  1677.  
  1678.         mpTopPlugin->SetPreviousHandler( pPlugin );
  1679.  
  1680.         mpTopPlugin = pPlugin;
  1681.     }
  1682.  
  1683.     mpTopPlugin->OnInitPlugin(); // notification
  1684. }
  1685.  
  1686. void wxFrameLayout::PopPlugin()
  1687. {
  1688.     wxASSERT( mpTopPlugin ); // DBG:: at least one plugin should be present
  1689.  
  1690.     cbPluginBase* pPopped = mpTopPlugin;
  1691.  
  1692.     mpTopPlugin = (cbPluginBase*)mpTopPlugin->GetNextHandler();
  1693.  
  1694.     delete pPopped;
  1695. }
  1696.  
  1697. void wxFrameLayout::PopAllPlugins()
  1698. {
  1699.     while( mpTopPlugin ) PopPlugin();
  1700. }
  1701.  
  1702. void wxFrameLayout::PushDefaultPlugins()
  1703. {
  1704.     // FIXME:: to much of the stuff for the default...
  1705.  
  1706.     AddPlugin( CLASSINFO( cbRowLayoutPlugin       ) );
  1707.     AddPlugin( CLASSINFO( cbBarDragPlugin         ) );
  1708.     AddPlugin( CLASSINFO( cbPaneDrawPlugin ) );
  1709. }
  1710.  
  1711. void wxFrameLayout::AddPlugin( wxClassInfo* pPlInfo, int paneMask )
  1712. {
  1713.     if ( FindPlugin ( pPlInfo ) ) return; // same type of plugin cannot be added twice
  1714.  
  1715.     cbPluginBase* pObj = (cbPluginBase*)pPlInfo->CreateObject();
  1716.  
  1717.     wxASSERT(pObj); // DBG:: plugin's class should be dynamic
  1718.  
  1719.     pObj->mPaneMask = paneMask;
  1720.     pObj->mpLayout  = this;
  1721.  
  1722.     PushPlugin( pObj );
  1723. }
  1724.  
  1725. void wxFrameLayout::AddPluginBefore( wxClassInfo* pNextPlInfo, wxClassInfo* pPlInfo, 
  1726.                                        int paneMask )
  1727. {
  1728.     wxASSERT( pNextPlInfo != pPlInfo ); // DBG:: no sense
  1729.  
  1730.     cbPluginBase* pNextPl = FindPlugin( pNextPlInfo );
  1731.  
  1732.     if ( !pNextPl )
  1733.     {
  1734.         AddPlugin( pPlInfo, paneMask );
  1735.  
  1736.         return;
  1737.     }
  1738.  
  1739.     // remove existing one if present
  1740.  
  1741.     cbPluginBase* pExistingPl = FindPlugin( pPlInfo );
  1742.     
  1743.     if ( pExistingPl ) RemovePlugin( pPlInfo );
  1744.  
  1745.     // create an instance 
  1746.  
  1747.     cbPluginBase* pNewPl = (cbPluginBase*)pPlInfo->CreateObject();
  1748.  
  1749.     wxASSERT(pNewPl); // DBG:: plugin's class should be dynamic
  1750.  
  1751.     // insert it to the chain
  1752.  
  1753.     if ( pNextPl->GetPreviousHandler() )
  1754.     
  1755.         pNextPl->GetPreviousHandler()->SetNextHandler( pNewPl );
  1756.     else
  1757.         mpTopPlugin = pNewPl;
  1758.  
  1759.     pNewPl->SetNextHandler( pNextPl );
  1760.  
  1761.     pNewPl->SetPreviousHandler( pNextPl->GetPreviousHandler() );
  1762.  
  1763.     pNextPl->SetPreviousHandler( pNewPl );
  1764.  
  1765.     // set it up
  1766.  
  1767.     pNewPl->mPaneMask = paneMask;
  1768.     pNewPl->mpLayout  = this;
  1769.  
  1770.     pNewPl->OnInitPlugin();
  1771. }
  1772.  
  1773. void wxFrameLayout::RemovePlugin( wxClassInfo* pPlInfo )
  1774. {
  1775.     cbPluginBase* pPlugin = FindPlugin( pPlInfo );
  1776.  
  1777.     if ( !pPlugin ) return; // it's OK to remove not-existing plugin ;-)
  1778.  
  1779.     if ( pPlugin->GetPreviousHandler() == NULL )
  1780.  
  1781.         mpTopPlugin = (cbPluginBase*)pPlugin->GetNextHandler();
  1782.  
  1783.     delete pPlugin;
  1784. }
  1785.  
  1786. cbPluginBase* wxFrameLayout::FindPlugin( wxClassInfo* pPlInfo )
  1787. {
  1788.     cbPluginBase *pCur = mpTopPlugin;
  1789.  
  1790.     while( pCur )
  1791.     {
  1792.         // NOTE:: it might appear useful matching plugin
  1793.         //        classes "polymorphically":
  1794.  
  1795.         if ( pCur->GetClassInfo()->IsKindOf( pPlInfo ) )
  1796.  
  1797.             return pCur;
  1798.  
  1799.         pCur = (cbPluginBase*)pCur->GetNextHandler();
  1800.     }
  1801.  
  1802.     return NULL;
  1803. }
  1804.  
  1805. /***** Implementation for class cbUpdateMgrData *****/
  1806.  
  1807. IMPLEMENT_DYNAMIC_CLASS( cbUpdateMgrData, wxObject )
  1808.  
  1809. cbUpdateMgrData::cbUpdateMgrData() 
  1810.  
  1811.     : mPrevBounds( -1,-1,0,0 ),
  1812.       mIsDirty( TRUE )           // inidicate initial change
  1813. {}
  1814.  
  1815. void cbUpdateMgrData::StoreItemState( const wxRect& boundsInParent )
  1816.     mPrevBounds = boundsInParent; 
  1817. }
  1818.  
  1819. void cbUpdateMgrData::SetDirty( bool isDirty )
  1820. {
  1821.     mIsDirty = isDirty;
  1822. }
  1823.  
  1824. void cbUpdateMgrData::SetCustomData( wxObject* pCustomData )
  1825. {
  1826.     mpCustomData = pCustomData;
  1827. }
  1828.  
  1829. /***** Implementation for class cbDockPane *****/
  1830.  
  1831. void wxBarIterator::Reset()
  1832. {
  1833.     mpRow = ( mpRows->Count() ) ? (*mpRows)[0] : NULL;
  1834.     mpBar = NULL;
  1835. }
  1836.  
  1837. wxBarIterator::wxBarIterator( RowArrayT& rows )
  1838.  
  1839.     : mpRows( &rows ),
  1840.       mpRow ( NULL  ),
  1841.       mpBar ( NULL  )
  1842. {
  1843.     Reset();
  1844. }
  1845.  
  1846. bool wxBarIterator::Next()
  1847. {      
  1848.     if ( mpRow )
  1849.     {
  1850.         if ( mpBar )
  1851.             mpBar = mpBar->mpNext;
  1852.         else
  1853.         {
  1854.             if ( mpRow->mBars.GetCount() == 0 )
  1855.             {
  1856.                 return FALSE; 
  1857.             }
  1858.  
  1859.             mpBar = mpRow->mBars[0];
  1860.         }
  1861.     
  1862.         if ( !mpBar )
  1863.         {   
  1864.             // skip to the next row
  1865.  
  1866.             mpRow = mpRow->mpNext;
  1867.     
  1868.             if ( mpRow )
  1869.     
  1870.                 mpBar = mpRow->mBars[0];
  1871.             else
  1872.                 return FALSE;
  1873.         }
  1874.     
  1875.         return TRUE;
  1876.     }
  1877.     else
  1878.         return FALSE;
  1879. }
  1880.  
  1881. cbBarInfo& wxBarIterator::BarInfo()
  1882. {
  1883.     return *mpBar;
  1884. }
  1885.  
  1886. cbRowInfo& wxBarIterator::RowInfo()
  1887. {
  1888.     return *mpRow;
  1889. }
  1890.  
  1891. /***** Implementation for class cbBarDimHandlerBase *****/
  1892.  
  1893. IMPLEMENT_ABSTRACT_CLASS( cbBarDimHandlerBase, wxObject )
  1894.  
  1895. cbBarDimHandlerBase::cbBarDimHandlerBase()
  1896.     : mRefCount(0)
  1897. {}
  1898.  
  1899. void cbBarDimHandlerBase::AddRef()
  1900. {
  1901.     ++mRefCount;
  1902. }
  1903.  
  1904. void cbBarDimHandlerBase::RemoveRef()
  1905. {
  1906.     if ( --mRefCount <= 0 ) delete this;
  1907. }
  1908.  
  1909. /***** Implementation for class cbDimInfo *****/
  1910.  
  1911. IMPLEMENT_DYNAMIC_CLASS( cbDimInfo, wxObject )
  1912.  
  1913. cbDimInfo::cbDimInfo() 
  1914.  
  1915.     : mVertGap ( 0 ), 
  1916.       mHorizGap( 0 ),
  1917.  
  1918.       mIsFixed(TRUE),
  1919.       mpHandler( NULL )
  1920. {
  1921.     size_t i;
  1922.     for ( i = 0; i != MAX_BAR_STATES; ++i )
  1923.     {
  1924.         mSizes[i].x = 20;
  1925.         mSizes[i].y = 20;
  1926.  
  1927.         mBounds[i] = wxRect( -1,-1,-1,-1 );
  1928.     }
  1929. }
  1930.  
  1931. cbDimInfo::cbDimInfo( cbBarDimHandlerBase* pDimHandler,
  1932.                       bool                 isFixed  )
  1933.  
  1934.     : mVertGap ( 0 ),
  1935.       mHorizGap( 0 ),
  1936.       mIsFixed ( isFixed  ),
  1937.  
  1938.       mpHandler( pDimHandler )
  1939. {
  1940.     if ( mpHandler )
  1941.     {
  1942.         // int vtad = *((int*)mpHandler);
  1943.         mpHandler->AddRef();
  1944.     }
  1945.     
  1946.     size_t i;
  1947.     for ( i = 0; i != MAX_BAR_STATES; ++i )
  1948.     {
  1949.         mSizes[i].x = -1;
  1950.         mSizes[i].y = -1;
  1951.  
  1952.         mBounds[i] = wxRect( -1,-1,-1,-1 );
  1953.     }
  1954. }
  1955.  
  1956. cbDimInfo::cbDimInfo( int dh_x, int dh_y,
  1957.                       int dv_x, int dv_y,
  1958.                       int f_x,  int f_y,
  1959.  
  1960.                       bool isFixed,
  1961.                       int horizGap,
  1962.                       int vertGap,
  1963.  
  1964.                       cbBarDimHandlerBase* pDimHandler
  1965.                     )
  1966.     : mVertGap  ( vertGap   ),
  1967.       mHorizGap ( horizGap  ),
  1968.       mIsFixed  ( isFixed   ),
  1969.       mpHandler( pDimHandler )
  1970. {
  1971.     if ( mpHandler )
  1972.     {
  1973.         // int vtad = *((int*)mpHandler);
  1974.         mpHandler->AddRef();
  1975.     }
  1976.  
  1977.     mSizes[wxCBAR_DOCKED_HORIZONTALLY].x = dh_x;
  1978.     mSizes[wxCBAR_DOCKED_HORIZONTALLY].y = dh_y;
  1979.     mSizes[wxCBAR_DOCKED_VERTICALLY  ].x = dv_x;
  1980.     mSizes[wxCBAR_DOCKED_VERTICALLY  ].y = dv_y;
  1981.     mSizes[wxCBAR_FLOATING           ].x = f_x;
  1982.     mSizes[wxCBAR_FLOATING           ].y = f_y;
  1983.  
  1984.     size_t i;
  1985.     for ( i = 0; i != MAX_BAR_STATES; ++i )
  1986.         mBounds[i] = wxRect( -1,-1,-1,-1 );
  1987. }    
  1988.  
  1989. cbDimInfo::cbDimInfo( int x, int y,  
  1990.                       bool isFixed, int gap, 
  1991.                       cbBarDimHandlerBase* pDimHandler)
  1992.   : mVertGap  ( gap ),
  1993.     mHorizGap ( gap ),
  1994.     mIsFixed  ( isFixed ),
  1995.     mpHandler( pDimHandler )
  1996. {
  1997.     if ( mpHandler )
  1998.     {
  1999.         // int vtad = *((int*)mpHandler);
  2000.         mpHandler->AddRef();
  2001.     }
  2002.  
  2003.     mSizes[wxCBAR_DOCKED_HORIZONTALLY].x = x;
  2004.     mSizes[wxCBAR_DOCKED_HORIZONTALLY].y = y;
  2005.     mSizes[wxCBAR_DOCKED_VERTICALLY  ].x = x;
  2006.     mSizes[wxCBAR_DOCKED_VERTICALLY  ].y = y;
  2007.     mSizes[wxCBAR_FLOATING           ].x = x;
  2008.     mSizes[wxCBAR_FLOATING           ].y = y;
  2009.     
  2010.     size_t i;
  2011.     for ( i = 0; i != MAX_BAR_STATES; ++i )
  2012.         mBounds[i] = wxRect( -1,-1,-1,-1 );
  2013. }
  2014.  
  2015. cbDimInfo::~cbDimInfo()
  2016. {
  2017.     if ( mpHandler ) 
  2018.         
  2019.         mpHandler->RemoveRef();
  2020. }
  2021.  
  2022. const cbDimInfo& cbDimInfo::operator=( const cbDimInfo& other )
  2023. {
  2024.     if ( this == &other )
  2025.         return *this;
  2026.  
  2027.     int i;
  2028.     for ( i = 0; i != MAX_BAR_STATES; ++i )
  2029.         mSizes[i] = other.mSizes[i];
  2030.  
  2031.     mIsFixed  = other.mIsFixed;
  2032.     mpHandler = other.mpHandler;
  2033.  
  2034.     mVertGap  = other.mVertGap;
  2035.     mHorizGap = other.mHorizGap;
  2036.  
  2037.     if ( mpHandler )
  2038.  
  2039.         mpHandler->AddRef();
  2040.  
  2041.     return *this;
  2042. }
  2043.  
  2044. /***** Implementation for structure cbCommonPaneProperties *****/
  2045.  
  2046. IMPLEMENT_DYNAMIC_CLASS( cbCommonPaneProperties, wxObject )
  2047.  
  2048. cbCommonPaneProperties::cbCommonPaneProperties(void)
  2049.  
  2050.     : mRealTimeUpdatesOn    ( TRUE  ),
  2051.       mOutOfPaneDragOn      ( TRUE  ),
  2052.       mExactDockPredictionOn( FALSE ),
  2053.       mNonDestructFrictionOn( FALSE ),
  2054.       mShow3DPaneBorderOn   ( TRUE  ),
  2055.       mBarFloatingOn        ( FALSE ),
  2056.       mRowProportionsOn     ( FALSE ),
  2057.       mColProportionsOn     ( TRUE  ),
  2058.       mBarCollapseIconsOn   ( FALSE ),
  2059.       mBarDragHintsOn       ( FALSE ),
  2060.  
  2061.       mMinCBarDim( 16, 16 ),
  2062.       mResizeHandleSize( 4 )
  2063. {}
  2064.  
  2065. cbCommonPaneProperties::cbCommonPaneProperties(const cbCommonPaneProperties& props)
  2066.  
  2067.     : wxObject(),
  2068.       mRealTimeUpdatesOn    (props.mRealTimeUpdatesOn),
  2069.       mOutOfPaneDragOn      (props.mOutOfPaneDragOn),
  2070.       mExactDockPredictionOn(props.mExactDockPredictionOn),
  2071.       mNonDestructFrictionOn(props.mNonDestructFrictionOn),
  2072.       mShow3DPaneBorderOn   (props.mShow3DPaneBorderOn),
  2073.       mBarFloatingOn        (props.mBarFloatingOn),
  2074.       mRowProportionsOn     (props.mRowProportionsOn),
  2075.       mColProportionsOn     (props.mColProportionsOn),
  2076.       mBarCollapseIconsOn   (props.mBarCollapseIconsOn),
  2077.       mBarDragHintsOn       (props.mBarDragHintsOn),
  2078.  
  2079.       mMinCBarDim(props.mMinCBarDim),
  2080.       mResizeHandleSize(props.mResizeHandleSize)
  2081. {}
  2082.  
  2083. cbCommonPaneProperties& cbCommonPaneProperties::operator=(const cbCommonPaneProperties& props)
  2084. {
  2085.     mRealTimeUpdatesOn     = props.mRealTimeUpdatesOn;
  2086.     mOutOfPaneDragOn       = props.mOutOfPaneDragOn;
  2087.     mExactDockPredictionOn = props.mExactDockPredictionOn;
  2088.     mNonDestructFrictionOn = props.mNonDestructFrictionOn;
  2089.     mShow3DPaneBorderOn    = props.mShow3DPaneBorderOn;
  2090.     mBarFloatingOn         = props.mBarFloatingOn;
  2091.     mRowProportionsOn      = props.mRowProportionsOn;
  2092.     mColProportionsOn      = props.mColProportionsOn;
  2093.     mBarCollapseIconsOn    = props.mBarCollapseIconsOn;
  2094.     mBarDragHintsOn        = props.mBarDragHintsOn;
  2095.     
  2096.     mMinCBarDim            = props.mMinCBarDim;
  2097.     mResizeHandleSize      = props.mResizeHandleSize;
  2098.  
  2099.     return *this;
  2100. }
  2101.  
  2102. /***** Implementation for class cbRowInfo *****/
  2103.  
  2104. IMPLEMENT_DYNAMIC_CLASS( cbRowInfo, wxObject )
  2105.  
  2106. cbRowInfo::cbRowInfo(void)
  2107.  
  2108.     : mNotFixedBarsCnt( FALSE ),
  2109.       mpNext          ( NULL ),
  2110.       mpPrev          ( NULL ),
  2111.       mpExpandedBar   ( NULL )
  2112. {}
  2113.  
  2114. cbRowInfo::~cbRowInfo()
  2115. {
  2116.     // nothing! all bars are removed using global bar
  2117.     // list in wxFrameLayout class
  2118. }
  2119.  
  2120. /***** Implementation for class cbBarInfo *****/
  2121.  
  2122. IMPLEMENT_DYNAMIC_CLASS( cbBarInfo, wxObject )
  2123.  
  2124. cbBarInfo::cbBarInfo(void)
  2125.  
  2126.     : mpRow( NULL ),
  2127.  
  2128.       mpNext( NULL ),
  2129.       mpPrev( NULL )
  2130. {}
  2131.  
  2132. cbBarInfo::~cbBarInfo()
  2133. {
  2134.     // nothing
  2135. }
  2136.  
  2137. /***** Implementation for class cbDockPane *****/
  2138.  
  2139. IMPLEMENT_DYNAMIC_CLASS( cbDockPane, wxObject )
  2140.  
  2141. // FIXME:: how to eliminate these cut&pasted constructors?
  2142.  
  2143. cbDockPane::cbDockPane(void)                             
  2144.     : mLeftMargin  ( 1 ),
  2145.       mRightMargin ( 1 ),
  2146.       mTopMargin   ( 1 ),
  2147.       mBottomMargin( 1 ),
  2148.       mPaneWidth ( 32768     ), // fake-up very large pane dims,
  2149.                                 // since the real dimensions of the pane may not 
  2150.                                 // be known, while inserting bars initially
  2151.       mPaneHeight( 32768     ),
  2152.       mAlignment ( -1   ),
  2153.       mpLayout   ( 0 ),
  2154.       mpStoredRow( NULL )
  2155. {}
  2156.  
  2157. cbDockPane::cbDockPane( int alignment, wxFrameLayout* pPanel )
  2158.                              
  2159.     :  mLeftMargin  ( 1 ),
  2160.       mRightMargin ( 1 ),
  2161.       mTopMargin   ( 1 ),
  2162.       mBottomMargin( 1 ),
  2163.       mPaneWidth ( 32768     ), // fake-up very large pane dims,
  2164.                                 // since the real dimensions of the pane may not 
  2165.                                 // be known, while inserting bars initially
  2166.       mPaneHeight( 32768     ),
  2167.       mAlignment ( alignment ),
  2168.       mpLayout   ( pPanel    ),
  2169.       mpStoredRow( NULL )    
  2170. {}
  2171.  
  2172. cbDockPane::~cbDockPane()
  2173. {
  2174.     size_t i;
  2175.     for ( i = 0; i != mRows.Count(); ++i )
  2176.         delete mRows[i];
  2177.  
  2178.     mRowShapeData.DeleteContents( TRUE );
  2179.     
  2180.     // NOTE:: control bar infromation structures are cleaned-up
  2181.     //        in wxFrameLayout's destructor, using global control-bar list
  2182. }
  2183.  
  2184. void cbDockPane::SetMargins( int top, int bottom, int left, int right )
  2185. {
  2186.     mTopMargin    = top;
  2187.     mBottomMargin = bottom;
  2188.     mLeftMargin   = left;
  2189.     mRightMargin  = right;
  2190. }
  2191.  
  2192. /*** helpers of cbDockPane ***/
  2193.  
  2194. void cbDockPane::PaintBarDecorations( cbBarInfo* pBar, wxDC& dc )
  2195. {
  2196.     cbDrawBarDecorEvent evt( pBar, dc, this );
  2197.  
  2198.     mpLayout->FirePluginEvent( evt );
  2199. }
  2200.  
  2201. void cbDockPane::PaintBarHandles( cbBarInfo* pBar, wxDC& dc )
  2202. {
  2203.     cbDrawBarHandlesEvent evt( pBar, dc, this );
  2204.  
  2205.     mpLayout->FirePluginEvent( evt );
  2206. }
  2207.  
  2208. void cbDockPane::PaintBar( cbBarInfo* pBar, wxDC& dc )
  2209. {
  2210.     PaintBarDecorations( pBar, dc );
  2211.     PaintBarHandles( pBar, dc );
  2212. }
  2213.  
  2214. void cbDockPane::PaintRowHandles( cbRowInfo* pRow, wxDC& dc )
  2215. {
  2216.     cbDrawRowHandlesEvent evt( pRow, dc, this );
  2217.  
  2218.     mpLayout->FirePluginEvent( evt );
  2219.  
  2220.     cbDrawRowDecorEvent evt1( pRow, dc, this );
  2221.  
  2222.     mpLayout->FirePluginEvent( evt1 );
  2223. }
  2224.  
  2225. void cbDockPane::PaintRowBackground ( cbRowInfo* pRow, wxDC& dc )
  2226. {
  2227.     cbDrawRowBkGroundEvent evt( pRow, dc, this );
  2228.  
  2229.     mpLayout->FirePluginEvent( evt );
  2230. }
  2231.  
  2232. void cbDockPane::PaintRowDecorations( cbRowInfo* pRow, wxDC& dc )
  2233. {
  2234.     size_t i = 0;
  2235.  
  2236.     // decorations first
  2237.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  2238.     
  2239.         PaintBarDecorations( pRow->mBars[i], dc );
  2240.  
  2241.     // then handles if present
  2242.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  2243.  
  2244.         PaintBarHandles( pRow->mBars[i], dc );
  2245. }
  2246.  
  2247. void cbDockPane::PaintRow( cbRowInfo* pRow, wxDC& dc )
  2248. {
  2249.     PaintRowBackground ( pRow, dc );
  2250.     PaintRowDecorations( pRow, dc );
  2251.     PaintRowHandles    ( pRow, dc );
  2252. }
  2253.  
  2254. void cbDockPane::PaintPaneBackground( wxDC& dc )
  2255. {
  2256.     cbDrawPaneBkGroundEvent evt( dc, this );
  2257.  
  2258.     mpLayout->FirePluginEvent( evt );
  2259. }
  2260.  
  2261. void cbDockPane::PaintPaneDecorations( wxDC& dc )
  2262. {
  2263.     cbDrawPaneDecorEvent evt( dc, this );
  2264.  
  2265.     mpLayout->FirePluginEvent( evt );
  2266. }
  2267.  
  2268. void cbDockPane::PaintPane( wxDC& dc )
  2269. {
  2270.     PaintPaneBackground( dc );
  2271.  
  2272.     size_t i = 0;
  2273.  
  2274.     // first decorations
  2275.     for ( i = 0; i != mRows.Count(); ++i )
  2276.     {
  2277.         PaintRowBackground( mRows[i], dc );
  2278.         PaintRowDecorations( mRows[i], dc );
  2279.     }
  2280.  
  2281.     // than handles
  2282.     for ( i = 0; i != mRows.Count(); ++i )
  2283.         PaintRowHandles( mRows[i], dc );
  2284.  
  2285.     // and finally
  2286.     PaintPaneDecorations( dc );
  2287. }
  2288.  
  2289. void cbDockPane::SizeBar( cbBarInfo* pBar )
  2290. {
  2291.     cbSizeBarWndEvent evt( pBar, this );
  2292.  
  2293.     mpLayout->FirePluginEvent( evt );
  2294.     return;
  2295. }
  2296.  
  2297. void cbDockPane::SizeRowObjects( cbRowInfo* pRow )
  2298. {
  2299.     size_t i;
  2300.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  2301.         SizeBar( pRow->mBars[i] );
  2302. }
  2303.  
  2304. void cbDockPane::SizePaneObjects()
  2305. {
  2306.     size_t i;
  2307.     for ( i = 0; i != mRows.Count(); ++i )
  2308.         SizeRowObjects( mRows[i] );
  2309. }
  2310.  
  2311. wxDC* cbDockPane::StartDrawInArea( const wxRect& area )
  2312. {
  2313.     wxDC* pDc = 0;
  2314.  
  2315.     cbStartDrawInAreaEvent evt( area, &pDc, this );
  2316.  
  2317.     mpLayout->FirePluginEvent( evt );
  2318.  
  2319.     return pDc;
  2320. }
  2321.  
  2322. void cbDockPane::FinishDrawInArea( const wxRect& area )
  2323. {
  2324.     cbFinishDrawInAreaEvent evt( area, this );
  2325.  
  2326.     mpLayout->FirePluginEvent( evt );
  2327. }
  2328.  
  2329. bool cbDockPane::IsFixedSize( cbBarInfo* pInfo )
  2330. {
  2331.     return ( pInfo->mDimInfo.mIsFixed );
  2332. }
  2333.  
  2334. int cbDockPane::GetNotFixedBarsCount( cbRowInfo* pRow )
  2335. {
  2336.     int cnt = 0;
  2337.  
  2338.     size_t i;
  2339.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  2340.     {
  2341.         if ( !pRow->mBars[i]->IsFixed() )
  2342.             ++cnt;
  2343.     }
  2344.  
  2345.     return cnt;
  2346. }
  2347.  
  2348. void cbDockPane::RemoveBar( cbBarInfo* pBar )
  2349. {
  2350.     bool needsRestoring = mProps.mNonDestructFrictionOn && 
  2351.                           mpStoredRow == pBar->mpRow;
  2352.  
  2353.     cbRemoveBarEvent evt( pBar, this );
  2354.  
  2355.     mpLayout->FirePluginEvent( evt );
  2356.  
  2357.     if ( needsRestoring )
  2358.     {
  2359.         SetRowShapeData( mpStoredRow, &mRowShapeData );
  2360.  
  2361.         mpStoredRow = NULL;
  2362.     }
  2363. }
  2364.  
  2365. void cbDockPane::SyncRowFlags( cbRowInfo* pRow )
  2366. {
  2367.     // setup mHasOnlyFixedBars flag for the row information
  2368.     pRow->mHasOnlyFixedBars = TRUE;
  2369.  
  2370.     pRow->mNotFixedBarsCnt = 0;
  2371.  
  2372.     size_t i;
  2373.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  2374.     {
  2375.         cbBarInfo& bar = *pRow->mBars[i];
  2376.  
  2377.         bar.mpRow = pRow;
  2378.  
  2379.         if ( !bar.IsFixed() )
  2380.         {
  2381.             pRow->mHasOnlyFixedBars = FALSE;
  2382.             ++pRow->mNotFixedBarsCnt;
  2383.         }
  2384.     }
  2385. }
  2386.  
  2387. void cbDockPane::FrameToPane( int* x, int* y )
  2388. {
  2389.     *x -= mLeftMargin;
  2390.     *y -= mTopMargin;
  2391.  
  2392.     if ( mAlignment == FL_ALIGN_TOP ||
  2393.          mAlignment == FL_ALIGN_BOTTOM 
  2394.        )
  2395.     {
  2396.         *x -= mBoundsInParent.x;
  2397.         *y -= mBoundsInParent.y;
  2398.     }
  2399.     else
  2400.     {
  2401.         int rx = *x, ry = *y;
  2402.  
  2403.         *x = ry - mBoundsInParent.y;
  2404.  
  2405.         *y = rx - mBoundsInParent.x;
  2406.     }
  2407. }
  2408.  
  2409. void cbDockPane::PaneToFrame( int* x, int* y )
  2410. {
  2411.     if ( mAlignment == FL_ALIGN_TOP ||
  2412.          mAlignment == FL_ALIGN_BOTTOM 
  2413.        )
  2414.     {
  2415.         *x += mBoundsInParent.x;
  2416.         *y += mBoundsInParent.y;
  2417.     }
  2418.     else
  2419.     {
  2420.         int rx = *x, ry = *y;
  2421.  
  2422.         *x = ry + mBoundsInParent.x;
  2423.  
  2424.         *y = mBoundsInParent.y + rx;
  2425.     }
  2426.  
  2427.     *x += mLeftMargin;
  2428.     *y += mTopMargin;
  2429. }
  2430.  
  2431. void cbDockPane::FrameToPane( wxRect* pRect )
  2432. {
  2433.     wxPoint upperLeft ( pRect->x, pRect->y );
  2434.     wxPoint lowerRight( pRect->x + pRect->width,
  2435.                         pRect->y + pRect->height );
  2436.  
  2437.     FrameToPane( &upperLeft.x,  &upperLeft.y  );
  2438.     FrameToPane( &lowerRight.x, &lowerRight.y );
  2439.  
  2440.     pRect->x = wxMin(upperLeft.x,lowerRight.x);
  2441.     pRect->y = wxMin(upperLeft.y,lowerRight.y);
  2442.  
  2443.     pRect->width  = abs( lowerRight.x - upperLeft.x );
  2444.     pRect->height = abs( lowerRight.y - upperLeft.y );
  2445. }
  2446.  
  2447. void cbDockPane::PaneToFrame( wxRect* pRect )
  2448. {
  2449.     wxPoint upperLeft ( pRect->x, pRect->y );
  2450.     wxPoint lowerRight( pRect->x + pRect->width,
  2451.                         pRect->y + pRect->height );
  2452.  
  2453.     PaneToFrame( &upperLeft.x,  &upperLeft.y  );
  2454.     PaneToFrame( &lowerRight.x, &lowerRight.y );
  2455.  
  2456.     //wxRect newRect = wxRect( upperLeft, lowerRight );
  2457.  
  2458.     pRect->x = wxMin(upperLeft.x,lowerRight.x);
  2459.     pRect->y = wxMin(upperLeft.y,lowerRight.y);
  2460.  
  2461.     pRect->width  = abs( lowerRight.x - upperLeft.x );
  2462.     pRect->height = abs( lowerRight.y - upperLeft.y );
  2463. }
  2464.  
  2465. int cbDockPane::GetRowAt( int paneY )
  2466. {
  2467.     if ( paneY < 0 )
  2468.         return -1;
  2469.  
  2470.     int curY = 0;
  2471.  
  2472.     size_t i = 0;
  2473.  
  2474.     for ( ; i != mRows.Count(); ++i )
  2475.     {
  2476.         int rowHeight = mRows[i]->mRowHeight;
  2477.  
  2478.         int third = rowHeight/3;
  2479.         
  2480.         if ( paneY >= curY && paneY < curY + third ) 
  2481.             return i-1;
  2482.  
  2483.         if ( paneY >= curY + third && paneY < curY + rowHeight - third ) 
  2484.             return i;
  2485.  
  2486.         curY += rowHeight;
  2487.     }
  2488.  
  2489.     return i;
  2490. }
  2491.  
  2492. int cbDockPane::GetRowAt( int upperY, int lowerY )
  2493. {
  2494.     /*
  2495.     // OLD STUFF::
  2496.     int range    = lowerY - upperY;
  2497.     int oneThird = range / 3;
  2498.  
  2499.     wxNode* pRow = mRows.First();
  2500.     int row = 0;
  2501.     int curY = 0;
  2502.  
  2503.     if ( lowerY <= 0 ) return -1;
  2504.  
  2505.     while( pRow )
  2506.     {
  2507.         int rowHeight = GetRowHeight( (wxList*)pRow->Data() );
  2508.  
  2509.         if ( upperY >= curY &&
  2510.              lowerY < curY ) return row;
  2511.  
  2512.         if ( upperY <= curY && 
  2513.              lowerY >= curY &&
  2514.              curY - upperY >= oneThird ) return row-1;
  2515.  
  2516.         if ( ( upperY <  curY + rowHeight && 
  2517.                lowerY >= curY + rowHeight &&
  2518.                curY + rowHeight - lowerY >= oneThird ) 
  2519.            )
  2520.             return row+1;
  2521.  
  2522.         if ( lowerY <= curY + rowHeight ) return row;
  2523.  
  2524.         ++row;
  2525.         curY += rowHeight;
  2526.         pRow = pRow->Next();
  2527.     }
  2528.     */
  2529.  
  2530.     int mid = upperY + (lowerY - upperY)/2;
  2531.  
  2532.     if ( mid < 0 )
  2533.         return -1;
  2534.  
  2535.     int curY = 0;
  2536.     size_t i = 0;
  2537.  
  2538.     for ( ; i != mRows.Count(); ++i )
  2539.     {
  2540.         int rowHeight = mRows[i]->mRowHeight;
  2541.  
  2542.         if ( mid >= curY && mid < curY + rowHeight ) return i;
  2543.  
  2544.         curY += rowHeight;
  2545.     }
  2546.  
  2547.     return i;
  2548. }
  2549.  
  2550. int cbDockPane::GetRowY( cbRowInfo* pRow )
  2551. {
  2552.     int curY = 0;
  2553.  
  2554.     size_t i;
  2555.     for ( i = 0; i != mRows.Count(); ++i )
  2556.     {
  2557.         if ( mRows[i] == pRow )
  2558.             break;
  2559.  
  2560.         curY += mRows[i]->mRowHeight;
  2561.     }
  2562.  
  2563.     return curY;
  2564. }
  2565.  
  2566. bool cbDockPane::HasNotFixedRowsAbove( cbRowInfo* pRow )
  2567. {
  2568.     while ( pRow->mpPrev )
  2569.     {
  2570.         pRow = pRow->mpPrev;
  2571.  
  2572.         if ( pRow->mHasOnlyFixedBars )
  2573.  
  2574.             return TRUE;
  2575.     } 
  2576.  
  2577.     return FALSE;
  2578. }
  2579.  
  2580. bool cbDockPane::HasNotFixedRowsBelow( cbRowInfo* pRow )
  2581. {
  2582.     while( pRow->mpNext )
  2583.     {
  2584.         pRow = pRow->mpNext;
  2585.  
  2586.         if ( pRow->mHasOnlyFixedBars )
  2587.  
  2588.             return TRUE;
  2589.     }
  2590.  
  2591.     return FALSE;
  2592. }
  2593.  
  2594. bool cbDockPane::HasNotFixedBarsLeft( cbBarInfo* pBar )
  2595. {
  2596.     while( pBar->mpPrev )
  2597.     {
  2598.         pBar = pBar->mpPrev;
  2599.  
  2600.         if ( pBar->IsFixed() )
  2601.  
  2602.             return TRUE;
  2603.     }
  2604.         
  2605.     return FALSE;
  2606. }
  2607.  
  2608. bool cbDockPane::HasNotFixedBarsRight( cbBarInfo* pBar )
  2609. {
  2610.     while( pBar->mpNext )
  2611.     {
  2612.         pBar = pBar->mpNext;
  2613.  
  2614.         if ( pBar->IsFixed() )
  2615.  
  2616.             return TRUE;
  2617.     }
  2618.         
  2619.     return FALSE;
  2620. }
  2621.  
  2622. void cbDockPane::CalcLengthRatios( cbRowInfo* pInRow )
  2623. {
  2624.     int totalWidth = 0;
  2625.  
  2626.     size_t i = 0;
  2627.  
  2628.     // calc current-maximal-total-length of all maximized bars
  2629.  
  2630.     for ( i = 0; i != pInRow->mBars.GetCount(); ++i )
  2631.     {
  2632.         cbBarInfo& bar = *pInRow->mBars[i];
  2633.  
  2634.         if ( !bar.IsFixed() )
  2635.             totalWidth += bar.mBounds.width;
  2636.     }
  2637.  
  2638.     // set up percentages of occupied space for each maximized bar
  2639.  
  2640.     for ( i = 0; i != pInRow->mBars.Count(); ++i )
  2641.     {
  2642.         cbBarInfo& bar = *pInRow->mBars[i];
  2643.  
  2644.         if ( !bar.IsFixed() )
  2645.             bar.mLenRatio = double(bar.mBounds.width)/double(totalWidth);
  2646.     }
  2647. }
  2648.  
  2649. void cbDockPane::RecalcRowLayout( cbRowInfo* pRow )
  2650. {
  2651.     cbLayoutRowEvent evt( pRow, this );
  2652.     
  2653.     mpLayout->FirePluginEvent( evt );
  2654. }
  2655.  
  2656. void cbDockPane::ExpandBar( cbBarInfo* pBar )
  2657. {
  2658.     mpLayout->GetUpdatesManager().OnStartChanges();
  2659.  
  2660.     if ( !pBar->mpRow->mpExpandedBar )
  2661.     {
  2662.         // save ratios only when there arent any bars expanded yet
  2663.  
  2664.         cbArrayFloat& ratios = pBar->mpRow->mSavedRatios;
  2665.  
  2666.         ratios.Clear();
  2667.         ratios.Alloc( pBar->mpRow->mNotFixedBarsCnt );
  2668.  
  2669.         cbBarInfo* pCur = pBar->mpRow->mBars[0];
  2670.  
  2671.         while( pCur )
  2672.         {
  2673.             if ( !pCur->IsFixed() )
  2674.             {
  2675.                 ratios.Add( 0.0 );
  2676.                 ratios[ ratios.GetCount() - 1 ] = pCur->mLenRatio; 
  2677.             }
  2678.  
  2679.             pCur = pCur->mpNext;
  2680.         }
  2681.     }
  2682.  
  2683.     cbBarInfo* pCur = pBar->mpRow->mBars[0];
  2684.  
  2685.     while( pCur )
  2686.     {
  2687.         pCur->mLenRatio = 0.0; // minimize the rest
  2688.  
  2689.         pCur = pCur->mpNext;
  2690.     }
  2691.  
  2692.     pBar->mLenRatio     = 1.0; // 100%
  2693.     pBar->mBounds.width = 0;
  2694.  
  2695.     pBar->mpRow->mpExpandedBar = pBar;
  2696.  
  2697.     mpLayout->RecalcLayout( FALSE );
  2698.  
  2699.     mpLayout->GetUpdatesManager().OnFinishChanges();
  2700.     mpLayout->GetUpdatesManager().UpdateNow();
  2701. }
  2702.  
  2703. void cbDockPane::ContractBar( cbBarInfo* pBar )
  2704. {
  2705.     mpLayout->GetUpdatesManager().OnStartChanges();
  2706.  
  2707.     // FIXME: What's the purpose of this???
  2708.     // double ratio = 1.0/ double( pBar->mpRow->mNotFixedBarsCnt );
  2709.  
  2710.     // restore ratios which were present before expansion
  2711.  
  2712.     cbBarInfo* pCur = pBar->mpRow->mBars[0];
  2713.  
  2714.     cbArrayFloat& ratios = pBar->mpRow->mSavedRatios;
  2715.  
  2716.     size_t i = 0;
  2717.  
  2718.     while( pCur )
  2719.     {
  2720.         if ( !pCur->IsFixed() )
  2721.         {
  2722.             pCur->mLenRatio = ratios[i];
  2723.             ++i;
  2724.         }
  2725.  
  2726.         pCur = pCur->mpNext;
  2727.     }
  2728.  
  2729.     ratios.Clear();
  2730.     ratios.Shrink();
  2731.  
  2732.     pBar->mpRow->mpExpandedBar = NULL;
  2733.  
  2734.     mpLayout->RecalcLayout( FALSE );
  2735.  
  2736.     mpLayout->GetUpdatesManager().OnFinishChanges();
  2737.     mpLayout->GetUpdatesManager().UpdateNow();
  2738. }
  2739.  
  2740. void cbDockPane::InitLinksForRow( cbRowInfo* pRow )
  2741. {
  2742.     size_t i;
  2743.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  2744.     {
  2745.         cbBarInfo& bar = *pRow->mBars[i];
  2746.  
  2747.         if ( i == 0 )
  2748.             bar.mpPrev = NULL;
  2749.         else
  2750.             bar.mpPrev = pRow->mBars[i-1];
  2751.  
  2752.         if ( i == pRow->mBars.Count() - 1 )
  2753.             bar.mpNext = NULL;
  2754.         else
  2755.             bar.mpNext = pRow->mBars[i+1];
  2756.     }
  2757. }
  2758.  
  2759. void cbDockPane::InitLinksForRows()
  2760. {
  2761.     size_t i;
  2762.     for ( i = 0; i != mRows.Count(); ++i )
  2763.     {
  2764.         cbRowInfo& row = *mRows[i];
  2765.  
  2766.         if ( i == 0 )
  2767.             row.mpPrev = NULL;
  2768.         else
  2769.             row.mpPrev = mRows[i-1];
  2770.  
  2771.         if ( i == mRows.Count() - 1 )
  2772.             row.mpNext = NULL;
  2773.         else
  2774.             row.mpNext = mRows[i+1];
  2775.     }
  2776. }
  2777.  
  2778. void cbDockPane::DoInsertBar( cbBarInfo* pBar, int rowNo )
  2779. {
  2780.     cbRowInfo* pRow = NULL;
  2781.  
  2782.     if ( rowNo == -1 || rowNo >= (int)mRows.Count() )
  2783.     {
  2784.         pRow = new cbRowInfo();
  2785.  
  2786.         if ( rowNo == -1 && mRows.Count() )
  2787.         
  2788.             mRows.Insert( pRow, 0 ); 
  2789.         else
  2790.             mRows.Add( pRow );
  2791.  
  2792.         InitLinksForRows();
  2793.     }
  2794.     else
  2795.     {
  2796.         pRow = mRows[rowNo];
  2797.  
  2798.         if ( mProps.mNonDestructFrictionOn == TRUE )
  2799.         {
  2800.             // store original shape of the row (before the bar is inserted)
  2801.  
  2802.             mpStoredRow = pRow;
  2803.             
  2804.             GetRowShapeData( mpStoredRow, &mRowShapeData );
  2805.         }
  2806.     }
  2807.  
  2808.     if ( pRow->mBars.Count() )
  2809.  
  2810.         pRow->mpExpandedBar = NULL;
  2811.  
  2812.     cbInsertBarEvent insEvt( pBar, pRow, this );
  2813.  
  2814.     mpLayout->FirePluginEvent( insEvt );
  2815.  
  2816.     mpLayout->GetUpdatesManager().OnRowWillChange( pRow, this );
  2817. }
  2818.  
  2819. void cbDockPane::InsertBar( cbBarInfo* pBarInfo, const wxRect& atRect )
  2820. {
  2821.     wxRect rect = atRect;
  2822.     FrameToPane( &rect );
  2823.  
  2824.     pBarInfo->mBounds.x      = rect.x;
  2825.     pBarInfo->mBounds.width  = rect.width;
  2826.     pBarInfo->mBounds.height = rect.height;
  2827.  
  2828.     int row = GetRowAt( rect.y, rect.y + rect.height );
  2829.  
  2830.     DoInsertBar( pBarInfo, row );
  2831. }
  2832.  
  2833. void cbDockPane::InsertBar( cbBarInfo* pBar, cbRowInfo* pIntoRow )
  2834. {
  2835.     cbInsertBarEvent insEvt( pBar, pIntoRow, this );
  2836.  
  2837.     mpLayout->FirePluginEvent( insEvt );
  2838.  
  2839.     mpLayout->GetUpdatesManager().OnRowWillChange( pIntoRow, this );
  2840. }
  2841.  
  2842. void cbDockPane::InsertBar( cbBarInfo* pBarInfo )
  2843. {
  2844.     // set transient properties
  2845.  
  2846.     pBarInfo->mpRow           = NULL;
  2847.     pBarInfo->mHasLeftHandle  = FALSE;
  2848.     pBarInfo->mHasRightHandle = FALSE;
  2849.     pBarInfo->mLenRatio       = 0.0;
  2850.  
  2851.     // set preferred bar dimensions, according to the state in which
  2852.     // the bar is being inserted
  2853.  
  2854.     pBarInfo->mBounds.width   = pBarInfo->mDimInfo.mSizes[ pBarInfo->mState ].x;
  2855.     pBarInfo->mBounds.height  = pBarInfo->mDimInfo.mSizes[ pBarInfo->mState ].y;
  2856.  
  2857.     DoInsertBar( pBarInfo, pBarInfo->mRowNo );
  2858. }
  2859.  
  2860. void cbDockPane::RemoveRow( cbRowInfo* pRow )
  2861. {
  2862.     size_t i;
  2863.     // first, hide all bar-windows in the removed row
  2864.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  2865.     {
  2866.         if ( pRow->mBars[i]->mpBarWnd )
  2867.             pRow->mBars[i]->mpBarWnd->Show( FALSE );
  2868.     }
  2869.  
  2870.     mRows.Remove( pRow );
  2871.  
  2872.     pRow->mUMgrData.SetDirty(TRUE);
  2873. }
  2874.  
  2875. void cbDockPane::InsertRow( cbRowInfo* pRow, cbRowInfo* pBeforeRow )
  2876. {
  2877.     if ( !pBeforeRow )
  2878.  
  2879.         mRows.Add( pRow );
  2880.     else
  2881.         mRows.Insert( pRow, mRows.Index( pBeforeRow ) );
  2882.  
  2883.     InitLinksForRows();
  2884.  
  2885.     pRow->mUMgrData.SetDirty(TRUE);
  2886.  
  2887.     size_t i;
  2888.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  2889.         pRow->mBars[i]->mUMgrData.SetDirty( TRUE );
  2890.  
  2891.     SyncRowFlags( pRow );
  2892. }
  2893.  
  2894. void cbDockPane::SetPaneWidth(int width)
  2895. {
  2896.     if ( IsHorizontal() )
  2897.         mPaneWidth = width - mLeftMargin - mRightMargin;
  2898.     else
  2899.         mPaneWidth = width - mTopMargin - mBottomMargin;
  2900. }
  2901.  
  2902.  
  2903. void cbDockPane::SetBoundsInParent( const wxRect& rect )
  2904. {
  2905.     mBoundsInParent = rect;
  2906.  
  2907.     // set pane dimensions in local coordinates
  2908.  
  2909.     if ( IsHorizontal() )
  2910.     {
  2911.         mPaneWidth  = mBoundsInParent.width  - ( mRightMargin + mLeftMargin   );
  2912.         mPaneHeight = mBoundsInParent.height - ( mTopMargin   + mBottomMargin );
  2913.     }
  2914.     else
  2915.     {
  2916.         mPaneWidth  = mBoundsInParent.height - ( mTopMargin   + mBottomMargin );
  2917.         mPaneHeight = mBoundsInParent.width  - ( mRightMargin + mLeftMargin   );
  2918.     }
  2919.  
  2920.     // convert bounding rectangles of all pane items into parent frame's coordinates
  2921.  
  2922.     wxBarIterator i( mRows );
  2923.  
  2924.     wxRect noMarginsRect = mBoundsInParent;
  2925.  
  2926.     noMarginsRect.x      += mLeftMargin;
  2927.     noMarginsRect.y      += mTopMargin;
  2928.     noMarginsRect.width  -= ( mLeftMargin + mRightMargin  );
  2929.     noMarginsRect.height -= ( mTopMargin  + mBottomMargin );
  2930.  
  2931.     // hide the whole pane, if it's bounds became reverted (i.e. pane vanished)
  2932.  
  2933.     if ( mBoundsInParent.width < 0 ||
  2934.          mBoundsInParent.height < 0 )
  2935.  
  2936.          hide_rect( mBoundsInParent );
  2937.  
  2938.     if ( noMarginsRect.width < 0 ||
  2939.          noMarginsRect.height < 0 )
  2940.     
  2941.         hide_rect( noMarginsRect   );
  2942.  
  2943.     // calculate mBoundsInParent for each item in the pane
  2944.  
  2945.     while( i.Next() )
  2946.     {
  2947.         cbBarInfo& bar = i.BarInfo();
  2948.  
  2949.         cbRowInfo* pRowInfo = bar.mpRow;
  2950.  
  2951.         // set up row info, if this is first bar in the row
  2952.  
  2953.         if ( pRowInfo && bar.mpPrev == NULL )
  2954.         {
  2955.             pRowInfo->mBoundsInParent.y      = pRowInfo->mRowY;
  2956.             pRowInfo->mBoundsInParent.x      = 0;
  2957.             pRowInfo->mBoundsInParent.width  = mPaneWidth;
  2958.             pRowInfo->mBoundsInParent.height = pRowInfo->mRowHeight;
  2959.  
  2960.             PaneToFrame( &pRowInfo->mBoundsInParent );
  2961.  
  2962.             clip_rect_against_rect( pRowInfo->mBoundsInParent, noMarginsRect );
  2963.         }
  2964.  
  2965.         wxRect bounds = bar.mBounds;
  2966.  
  2967.         // exclude dimensions of handles, when calculating
  2968.         // bar's bounds in parent (i.e. "visual bounds")
  2969.  
  2970.         if ( bar.mHasLeftHandle )
  2971.         {
  2972.             bounds.x     += mProps.mResizeHandleSize;
  2973.             bounds.width -= mProps.mResizeHandleSize;
  2974.         }
  2975.  
  2976.         if ( bar.mHasRightHandle )
  2977.         
  2978.             bounds.width -= mProps.mResizeHandleSize;
  2979.  
  2980.         PaneToFrame( &bounds );
  2981.  
  2982.         clip_rect_against_rect( bounds, noMarginsRect );
  2983.  
  2984.         bar.mBoundsInParent = bounds;
  2985.     }
  2986. }
  2987.  
  2988. bool cbDockPane::BarPresent( cbBarInfo* pBar )
  2989. {
  2990.     wxBarIterator iter( mRows );
  2991.  
  2992.     while( iter.Next() )
  2993.     
  2994.         if ( &iter.BarInfo() == pBar ) return TRUE;
  2995.  
  2996.     return FALSE;
  2997. }
  2998.  
  2999. cbRowInfo* cbDockPane::GetRow( int row )
  3000. {
  3001.     if ( row >= (int)mRows.Count() ) return NULL;
  3002.  
  3003.     return mRows[ row ];
  3004. }
  3005.  
  3006. int cbDockPane::GetRowIndex( cbRowInfo* pRow )
  3007. {
  3008.     size_t i;
  3009.     for ( i = 0; i != mRows.Count(); ++i )
  3010.     {
  3011.         if ( mRows[i] == pRow ) 
  3012.             return i;
  3013.     }
  3014.  
  3015.     wxFAIL_MSG("Row must be present to call cbDockPane::GetRowIndex()");
  3016.  
  3017.     return 0;
  3018. }
  3019.  
  3020. int cbDockPane::GetPaneHeight()
  3021. {
  3022.     // first, recalculate row heights and the Y-positions
  3023.  
  3024.     cbLayoutRowsEvent evt( this );
  3025.     mpLayout->FirePluginEvent( evt );
  3026.  
  3027.     int height = 0;
  3028.  
  3029.     if ( IsHorizontal() )
  3030.     
  3031.         height += mTopMargin  + mBottomMargin;
  3032.     else
  3033.         height += mLeftMargin + mRightMargin;
  3034.  
  3035.     int count = mRows.Count();
  3036.  
  3037.     if ( count )
  3038.     
  3039.         height += mRows[count-1]->mRowY + mRows[count-1]->mRowHeight;
  3040.  
  3041.     return height;
  3042. }
  3043.  
  3044. int cbDockPane::GetAlignment()
  3045. {
  3046.     return mAlignment;
  3047. }
  3048.  
  3049. bool cbDockPane::MatchesMask( int paneMask )
  3050. {
  3051.     int thisMask = 0;
  3052.  
  3053.     // FIXME:: use array instead of switch()
  3054.  
  3055.     switch (mAlignment)
  3056.     {
  3057.         case FL_ALIGN_TOP    : thisMask = FL_ALIGN_TOP_PANE;   break;
  3058.         case FL_ALIGN_BOTTOM : thisMask = FL_ALIGN_BOTTOM_PANE;break;
  3059.         case FL_ALIGN_LEFT   : thisMask = FL_ALIGN_LEFT_PANE;  break;
  3060.         case FL_ALIGN_RIGHT  : thisMask = FL_ALIGN_RIGHT_PANE; break;
  3061.  
  3062.         default:
  3063.             wxFAIL_MSG("Bad FL alignment type detected in cbDockPane::MatchesMask()");
  3064.     }
  3065.  
  3066.     return ( thisMask & paneMask ) != 0;
  3067. }
  3068.  
  3069. void cbDockPane::RecalcLayout()
  3070. {
  3071.     // first, reposition rows and items vertically
  3072.  
  3073.     cbLayoutRowsEvent evt( this );
  3074.     mpLayout->FirePluginEvent( evt );
  3075.  
  3076.     // then horizontally in each row 
  3077.  
  3078.     size_t i;
  3079.     for ( i = 0; i != mRows.Count(); ++i )
  3080.         RecalcRowLayout( mRows[i] );
  3081. }
  3082.  
  3083. int cbDockPane::GetDockingState()
  3084. {
  3085.     if ( mAlignment == FL_ALIGN_TOP || 
  3086.          mAlignment == FL_ALIGN_BOTTOM )
  3087.     {
  3088.         return wxCBAR_DOCKED_HORIZONTALLY;
  3089.     }
  3090.     else
  3091.         return wxCBAR_DOCKED_VERTICALLY;
  3092. }
  3093.  
  3094. inline bool cbDockPane::HasPoint( const wxPoint& pos, int x, int y, 
  3095.                                   int width, int height )
  3096. {
  3097.     return ( pos.x >= x && 
  3098.              pos.y >= y &&
  3099.              pos.x < x + width &&
  3100.              pos.y < y + height   );
  3101. }
  3102.  
  3103. int cbDockPane::HitTestPaneItems( const wxPoint& pos,
  3104.                                   cbRowInfo**    ppRow,
  3105.                                   cbBarInfo**    ppBar
  3106.                                 )
  3107. {
  3108.     (*ppRow) = NULL;
  3109.     (*ppBar) = NULL;
  3110.  
  3111.     size_t i;
  3112.     for ( i = 0; i != mRows.Count(); ++i )
  3113.     {
  3114.         cbRowInfo& row = *mRows[i];
  3115.  
  3116.         *ppRow = &row;
  3117.  
  3118.         // hit-test handles of the row, if present
  3119.  
  3120.         if ( row.mHasUpperHandle )
  3121.         {
  3122.             if ( HasPoint( pos, 0, row.mRowY,
  3123.                            row.mRowWidth, mProps.mResizeHandleSize ) )
  3124.  
  3125.                 return CB_UPPER_ROW_HANDLE_HITTED;
  3126.         }
  3127.         else
  3128.         if ( row.mHasLowerHandle )
  3129.         {
  3130.             if ( HasPoint( pos, 0, row.mRowY + row.mRowHeight - mProps.mResizeHandleSize, 
  3131.                            row.mRowWidth, mProps.mResizeHandleSize ) )
  3132.  
  3133.                     return CB_LOWER_ROW_HANDLE_HITTED;
  3134.         }
  3135.  
  3136.         // hit-test bar handles and bar content
  3137.  
  3138.         size_t k;
  3139.         for ( k = 0; k != row.mBars.Count(); ++k )
  3140.         {
  3141.             cbBarInfo& bar    = *row.mBars[k];
  3142.             wxRect&    bounds = bar.mBounds;
  3143.  
  3144.             *ppBar = &bar;
  3145.  
  3146.             if ( bar.mHasLeftHandle )
  3147.             {
  3148.                 if ( HasPoint( pos, bounds.x, bounds.y,
  3149.                                mProps.mResizeHandleSize, bounds.height ) )
  3150.  
  3151.                     return CB_LEFT_BAR_HANDLE_HITTED;
  3152.             }
  3153.             else
  3154.             if ( bar.mHasRightHandle )
  3155.             {
  3156.                 if ( HasPoint( pos, bounds.x + bounds.width - mProps.mResizeHandleSize, bounds.y,
  3157.                                mProps.mResizeHandleSize, bounds.height ) )
  3158.                 
  3159.                     return CB_RIGHT_BAR_HANDLE_HITTED;
  3160.             }
  3161.  
  3162.             if ( HasPoint( pos, bounds.x, bounds.y, bounds.width, bounds.height ) )
  3163.                 return CB_BAR_CONTENT_HITTED;
  3164.  
  3165.         } // hit-test next bar
  3166.  
  3167.     } // next row
  3168.  
  3169.     return CB_NO_ITEMS_HITTED;
  3170. }
  3171.  
  3172. void cbDockPane::GetBarResizeRange( cbBarInfo* pBar, int* from, int *till,
  3173.                                     bool forLeftHandle )
  3174. {
  3175.     cbBarInfo* pGivenBar = pBar;
  3176.  
  3177.     int notFree = 0;
  3178.  
  3179.     // calc unavailable space from the left
  3180.  
  3181.     while( pBar->mpPrev )
  3182.     {
  3183.         pBar = pBar->mpPrev;
  3184.  
  3185.         if ( !pBar->IsFixed() ) notFree += mProps.mMinCBarDim.x;
  3186.                                 else notFree += pBar->mBounds.width;
  3187.     }
  3188.  
  3189.     *from = notFree;
  3190.  
  3191.     pBar = pGivenBar;
  3192.  
  3193.     notFree = 0;
  3194.  
  3195.     // calc unavailable space from the right
  3196.  
  3197.     while( pBar->mpNext )
  3198.     {
  3199.         pBar = pBar->mpNext;
  3200.  
  3201.         if ( pBar->mBounds.x >= mPaneWidth ) break;
  3202.  
  3203.         // treat not-fixed bars as minimized
  3204.  
  3205.         if ( !pBar->IsFixed() ) 
  3206.             
  3207.             notFree += mProps.mMinCBarDim.x;
  3208.         else 
  3209.         {
  3210.             if ( pBar->mBounds.x + pBar->mBounds.width >= mPaneWidth )
  3211.             {
  3212.                 notFree += mPaneWidth - pBar->mBounds.x;
  3213.                 break;
  3214.             }
  3215.             else
  3216.                 notFree += pBar->mBounds.width;
  3217.         }
  3218.  
  3219.     } 
  3220.  
  3221.     *till = mPaneWidth - notFree;
  3222.  
  3223.     // do not let resizing totally deform the bar itself
  3224.  
  3225.     if ( forLeftHandle )
  3226.     
  3227.         (*till) -= mProps.mMinCBarDim.x;
  3228.     else
  3229.     
  3230.         (*from) += mProps.mMinCBarDim.x;
  3231. }
  3232.  
  3233. int cbDockPane::GetMinimalRowHeight( cbRowInfo* pRow )
  3234. {
  3235.     int height = mProps.mMinCBarDim.y;
  3236.  
  3237.     size_t i;
  3238.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  3239.     {
  3240.         if ( pRow->mBars[i]->IsFixed() )
  3241.             height = wxMax( height, pRow->mBars[i]->mBounds.height );
  3242.     }
  3243.  
  3244.     if ( pRow->mHasUpperHandle )
  3245.         height += mProps.mResizeHandleSize;
  3246.  
  3247.     if ( pRow->mHasLowerHandle )
  3248.         height += mProps.mResizeHandleSize;
  3249.     
  3250.     return height;
  3251. }
  3252.  
  3253. void cbDockPane::SetRowHeight( cbRowInfo* pRow, int newHeight )
  3254. {
  3255.     if ( pRow->mHasUpperHandle )
  3256.  
  3257.         newHeight -= mProps.mResizeHandleSize;
  3258.  
  3259.     if ( pRow->mHasLowerHandle )
  3260.  
  3261.         newHeight -= mProps.mResizeHandleSize;
  3262.  
  3263.     size_t i;
  3264.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  3265.     {
  3266.         if ( !pRow->mBars[i]->IsFixed() )
  3267.             pRow->mBars[i]->mBounds.height = newHeight;
  3268.     }
  3269. }
  3270.  
  3271. void cbDockPane::GetRowResizeRange( cbRowInfo* pRow, int* from, int* till,
  3272.                                     bool forUpperHandle )
  3273. {
  3274.     cbRowInfo* pGivenRow = pRow;
  3275.  
  3276.     // calc unavailable space from above
  3277.  
  3278.     int notFree = 0;
  3279.  
  3280.     while( pRow->mpPrev )
  3281.     {
  3282.         pRow = pRow->mpPrev;
  3283.  
  3284.         notFree += GetMinimalRowHeight( pRow );
  3285.  
  3286.     };
  3287.  
  3288.     *from = notFree;    
  3289.  
  3290.     // allow accupy the client window space by resizing pane rows
  3291.     if ( mAlignment == FL_ALIGN_BOTTOM )
  3292.  
  3293.         *from -= mpLayout->GetClientHeight();
  3294.     else
  3295.     if ( mAlignment == FL_ALIGN_RIGHT )
  3296.  
  3297.         *from -= mpLayout->GetClientWidth();
  3298.  
  3299.     // calc unavailable space from below
  3300.  
  3301.     pRow = pGivenRow;
  3302.  
  3303.     notFree = 0;
  3304.  
  3305.     while( pRow->mpNext )
  3306.     {
  3307.         pRow = pRow->mpNext;
  3308.  
  3309.         notFree += GetMinimalRowHeight( pRow );
  3310.  
  3311.     }
  3312.  
  3313.     *till = mPaneHeight - notFree;  
  3314.  
  3315.     // allow adjustinig pane space vs. client window space by resizing pane row heights
  3316.  
  3317.     if ( mAlignment == FL_ALIGN_TOP )
  3318.  
  3319.         *till += mpLayout->GetClientHeight();
  3320.     else
  3321.     if ( mAlignment == FL_ALIGN_LEFT )
  3322.  
  3323.         *till += mpLayout->GetClientWidth();
  3324.  
  3325.     // do not let the resizing of the row totally squeeze the row itself
  3326.  
  3327.     cbRowInfo& row = *pGivenRow;
  3328.  
  3329.     if ( forUpperHandle )
  3330.     {   
  3331.         *till = row.mRowY + row.mRowHeight - GetMinimalRowHeight( pGivenRow );
  3332.  
  3333.         if ( row.mHasUpperHandle )
  3334.  
  3335.             *till -= mProps.mResizeHandleSize;
  3336.     }
  3337.     else
  3338.     {
  3339.         *from += GetMinimalRowHeight( pGivenRow );
  3340.  
  3341.         if ( row.mHasLowerHandle )
  3342.  
  3343.             *from -= mProps.mResizeHandleSize;
  3344.     }
  3345. }
  3346.  
  3347. void cbDockPane::ResizeRow( cbRowInfo* pRow, int ofs, 
  3348.                             bool forUpperHandle )
  3349. {
  3350.     cbResizeRowEvent evt( pRow, ofs, forUpperHandle, this );
  3351.  
  3352.     mpLayout->FirePluginEvent( evt );
  3353. }
  3354.  
  3355. void cbDockPane::ResizeBar( cbBarInfo* pBar, int ofs, 
  3356.                             bool forLeftHandle )
  3357. {
  3358.     pBar->mpRow->mpExpandedBar = NULL;
  3359.  
  3360.     mpLayout->GetUpdatesManager().OnStartChanges();
  3361.  
  3362.     wxRect&  bounds = pBar->mBounds;
  3363.  
  3364.     if ( forLeftHandle )
  3365.     {
  3366.         // do not allow bar width become less then minimal
  3367.         if ( bounds.x + ofs > bounds.x + bounds.width - mProps.mMinCBarDim.x )
  3368.         {
  3369.             bounds.width = mProps.mMinCBarDim.x;
  3370.             bounds.x += ofs;
  3371.         }
  3372.         else
  3373.         {
  3374.             bounds.x     += ofs;
  3375.             bounds.width -= ofs;
  3376.         }
  3377.     }
  3378.     else
  3379.     {
  3380.         // move bar left if necessary       
  3381.         if ( bounds.width + ofs < mProps.mMinCBarDim.x )
  3382.         {
  3383.             bounds.x     = bounds.x + bounds.width + ofs - mProps.mMinCBarDim.x;
  3384.             bounds.width = mProps.mMinCBarDim.x;
  3385.         }
  3386.         else
  3387.             // resize right border only
  3388.             bounds.width += ofs;
  3389.     }
  3390.  
  3391.  
  3392.     cbRowInfo* pToRow = pBar->mpRow;
  3393.  
  3394.     this->RemoveBar( pBar );
  3395.  
  3396.     InsertBar( pBar, pToRow );
  3397.  
  3398.     mpLayout->RecalcLayout(FALSE);
  3399.  
  3400.     mpLayout->GetUpdatesManager().OnFinishChanges();
  3401.     mpLayout->GetUpdatesManager().UpdateNow();
  3402. }
  3403.  
  3404.  
  3405. /*** row/bar resizing related methods ***/
  3406.  
  3407. void cbDockPane::DrawVertHandle( wxDC& dc, int x, int y, int height )
  3408. {
  3409.     int lower = y + height;
  3410.  
  3411.     dc.SetPen( mpLayout->mLightPen );
  3412.     dc.DrawLine( x,y, x, lower );
  3413.  
  3414.     dc.SetPen( mpLayout->mGrayPen );
  3415.     int i;
  3416.     for ( i = 0; i != mProps.mResizeHandleSize-1; ++i )
  3417.     {
  3418.         ++x;
  3419.         dc.DrawLine( x,y, x, lower );
  3420.     }
  3421.  
  3422.     dc.SetPen( mpLayout->mDarkPen );
  3423.     ++x;
  3424.     dc.DrawLine( x,y, x, lower );
  3425.  
  3426.     dc.SetPen( mpLayout->mBlackPen );
  3427.     ++x;
  3428.     dc.DrawLine( x,y, x, lower );
  3429. }
  3430.  
  3431. void cbDockPane::DrawHorizHandle( wxDC& dc, int x, int y, int width  )
  3432. {
  3433.     int right = x + width;
  3434.  
  3435.     dc.SetPen( mpLayout->mLightPen );
  3436.     dc.DrawLine( x,y, right, y );
  3437.  
  3438.     dc.SetPen( mpLayout->mGrayPen );
  3439.  
  3440.     int i;
  3441.     for ( i = 0; i != mProps.mResizeHandleSize-1; ++i )
  3442.     {
  3443.         ++y;
  3444.         dc.DrawLine( x,y, right, y );
  3445.     }
  3446.  
  3447.     dc.SetPen( mpLayout->mDarkPen );
  3448.     dc.DrawLine( x,y, right, ++y );
  3449.  
  3450.     dc.SetPen( mpLayout->mBlackPen );
  3451.     dc.DrawLine( x,y, right, ++y );
  3452. }
  3453.  
  3454. cbBarInfo* cbDockPane::GetBarInfoByWindow( wxWindow* pBarWnd )
  3455. {
  3456.     wxBarIterator i( mRows );
  3457.  
  3458.     while( i.Next() )
  3459.     
  3460.         if ( i.BarInfo().mpBarWnd == pBarWnd )
  3461.  
  3462.             return &i.BarInfo();
  3463.  
  3464.     return NULL;
  3465. }
  3466.  
  3467. void cbDockPane::GetRowShapeData( cbRowInfo* pRow, wxList* pLst )
  3468. {
  3469.     pLst->DeleteContents( TRUE );
  3470.     pLst->Clear();
  3471.  
  3472.     size_t i;
  3473.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  3474.     {
  3475.         cbBarInfo& bar = *pRow->mBars[i];
  3476.  
  3477.         cbBarShapeData* pData = new cbBarShapeData();
  3478.  
  3479.         pLst->Append( (wxObject*)pData );
  3480.  
  3481.         pData->mBounds   = bar.mBounds;
  3482.         pData->mLenRatio = bar.mLenRatio;
  3483.     }
  3484. }
  3485.  
  3486. void cbDockPane::SetRowShapeData( cbRowInfo* pRow, wxList* pLst )
  3487. {
  3488.     if ( pLst->First() == NULL )
  3489.         return;
  3490.  
  3491.     wxNode* pData = pLst->First();
  3492.  
  3493.     size_t i;
  3494.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  3495.     {
  3496.         wxASSERT( pData ); // DBG::
  3497.  
  3498.         cbBarInfo& bar = *pRow->mBars[i];;
  3499.  
  3500.         cbBarShapeData& data = *((cbBarShapeData*)pData->Data());
  3501.  
  3502.         bar.mBounds   = data.mBounds;
  3503.         bar.mLenRatio = data.mLenRatio;
  3504.  
  3505.         pData = pData->Next();
  3506.     }
  3507. }
  3508.  
  3509. /***** Implementation for class cbUpdatesManagerBase *****/
  3510.  
  3511. IMPLEMENT_ABSTRACT_CLASS( cbUpdatesManagerBase, wxObject )
  3512.  
  3513. /***** Implementation for class cbPluginBase *****/
  3514.  
  3515. IMPLEMENT_ABSTRACT_CLASS( cbPluginBase, wxEvtHandler )
  3516.  
  3517. cbPluginBase::~cbPluginBase()
  3518. {
  3519.     // nothing
  3520. }
  3521.  
  3522. bool cbPluginBase::ProcessEvent(wxEvent& event)
  3523. {
  3524.     if ( mPaneMask == wxALL_PANES ) 
  3525.  
  3526.         return wxEvtHandler::ProcessEvent( event );
  3527.  
  3528.     // extract mask info. from received event
  3529.  
  3530.     cbPluginEvent& evt = *( (cbPluginEvent*)&event );
  3531.  
  3532.     if ( evt.mpPane == 0 &&
  3533.          mPaneMask  == wxALL_PANES )
  3534.  
  3535.          return wxEvtHandler::ProcessEvent( event );
  3536.  
  3537.     int mask = 0;
  3538.  
  3539.     switch ( evt.mpPane->mAlignment )
  3540.     {
  3541.         case FL_ALIGN_TOP    : mask = FL_ALIGN_TOP_PANE;   break;
  3542.         case FL_ALIGN_BOTTOM : mask = FL_ALIGN_BOTTOM_PANE;break;
  3543.         case FL_ALIGN_LEFT   : mask = FL_ALIGN_LEFT_PANE;  break;
  3544.         case FL_ALIGN_RIGHT  : mask = FL_ALIGN_RIGHT_PANE; break;
  3545.     }
  3546.  
  3547.     // if event's pane maks matches the plugin's mask
  3548.  
  3549.     if ( mPaneMask & mask ) 
  3550.  
  3551.         return wxEvtHandler::ProcessEvent( event );
  3552.  
  3553.     // otherwise pass to the next handler if present
  3554.  
  3555.     if ( GetNextHandler() && GetNextHandler()->ProcessEvent( event ) )
  3556.  
  3557.         return TRUE;
  3558.     else
  3559.         return FALSE;
  3560. }
  3561.  
  3562.