home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / contrib / src / fl / controlbar.cpp < prev    next >
C/C++ Source or Header  |  2002-08-16  |  88KB  |  3,562 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 2002/08/16 10:31:53 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.     if ( event.GetEventObject() == (wxObject*) mpFrame )
  1159.     {
  1160.         GetUpdatesManager().OnStartChanges();
  1161.         RecalcLayout(TRUE);
  1162.         GetUpdatesManager().OnFinishChanges();
  1163.         GetUpdatesManager().UpdateNow();
  1164.     }
  1165.  
  1166. }
  1167.  
  1168. /*** protected members ***/
  1169.  
  1170. void wxFrameLayout::HideBarWindows()
  1171. {
  1172.     size_t i;
  1173.     for ( i = 0; i != mAllBars.Count(); ++i )
  1174.         if ( mAllBars[i]->mpBarWnd && mAllBars[i]->mState != wxCBAR_FLOATING )
  1175.             mAllBars[i]->mpBarWnd->Show( FALSE );
  1176.  
  1177.     // then floated frames
  1178.  
  1179.     ShowFloatedWindows( FALSE );
  1180.  
  1181.     if ( mpFrameClient )
  1182.  
  1183.         mpFrameClient->Show( FALSE );
  1184. }
  1185.  
  1186. void wxFrameLayout::UnhookFromFrame()
  1187. {
  1188.     // NOTE:: the SetEvtHandlerEnabled() method is not used
  1189.     //        here, since it is assumed that unhooking layout
  1190.     //        from window may result destroying of the layout itself
  1191.     //       
  1192.     //        BUG BUG BUG (wx):: this would not be a problem if 
  1193.     //                           wxEvtHandler's destructor checked if 
  1194.     //                           this handler is currently the top-most 
  1195.     //                           handler of some window, and additionally 
  1196.     //                           to the reconnecting itself from the chain.
  1197.     //                           It would also re-setup current event handler 
  1198.     //                           of the window using wxWindow::SetEventHandler()
  1199.  
  1200.     // FOR NOW::
  1201.  
  1202.     if ( mpFrame->GetEventHandler() == this )
  1203.     {
  1204.         mpFrame->PopEventHandler();
  1205.         return;
  1206.     }
  1207.  
  1208.     if ( mpFrame )
  1209.     {
  1210.         if ( this == mpFrame->GetEventHandler() )
  1211.         {
  1212.             mpFrame->SetEventHandler( this->GetNextHandler() );
  1213.         }
  1214.         else
  1215.         {
  1216.             wxEvtHandler* pCur = mpFrame->GetEventHandler();
  1217.  
  1218.             while ( pCur )
  1219.             {
  1220.                 if ( pCur == this )
  1221.                     break;
  1222.  
  1223.                 pCur = pCur->GetNextHandler();
  1224.             }
  1225.  
  1226.             // do not try to unhook ourselves if we're not hooked yet
  1227.             if ( !pCur )
  1228.                 return;
  1229.         }
  1230.  
  1231.         if ( GetPreviousHandler() )
  1232.             GetPreviousHandler()->SetNextHandler( GetNextHandler() );
  1233.         else
  1234.         {
  1235.             mpFrame->PopEventHandler();
  1236.             return;
  1237.         }
  1238.  
  1239.         if ( GetNextHandler() )
  1240.             GetNextHandler()->SetPreviousHandler( GetPreviousHandler() );
  1241.  
  1242.         SetNextHandler( NULL );
  1243.         SetPreviousHandler( NULL );
  1244.     }
  1245. }
  1246.  
  1247. void wxFrameLayout::HookUpToFrame()
  1248. {
  1249.     // unhook us first, we're already hooked up
  1250.  
  1251.     UnhookFromFrame();
  1252.  
  1253.     // put ourselves on top
  1254.  
  1255.     mpFrame->PushEventHandler( this );
  1256. }
  1257.  
  1258. cbDockPane* wxFrameLayout::GetBarPane( cbBarInfo* pBar )
  1259. {
  1260.     int i;
  1261.     for ( i = 0; i != MAX_PANES; ++i )
  1262.         if ( mPanes[i]->BarPresent( pBar ) )
  1263.             return mPanes[i];
  1264.  
  1265.     return NULL;
  1266. }
  1267.  
  1268. void wxFrameLayout::CreateCursors()
  1269. {
  1270.     /*
  1271.     // FIXME:: The below code somehow doesn't work - cursors remain unchanged
  1272.     char bits[64];
  1273.     
  1274.     set_cursor_bits( _gHorizCursorImg, bits, 32, 16 );
  1275.  
  1276.     mpHorizCursor = new wxCursor( bits, 32, 16 );
  1277.  
  1278.     set_cursor_bits( _gVertCursorImg, bits, 32, 16 );
  1279.  
  1280.     mpVertCursor  = new wxCursor( bits, 32, 16 );
  1281.     */
  1282.  
  1283.     // FOR NOW:: use standard ones
  1284.  
  1285.     mpHorizCursor  = new wxCursor(wxCURSOR_SIZEWE);
  1286.     mpVertCursor   = new wxCursor(wxCURSOR_SIZENS);
  1287.     mpNormalCursor = new wxCursor(wxCURSOR_ARROW );
  1288.     mpDragCursor   = new wxCursor(wxCURSOR_CROSS );
  1289.     mpNECursor     = new wxCursor(wxCURSOR_NO_ENTRY);
  1290.  
  1291.     mFloatingPosStep.x = 25;
  1292.     mFloatingPosStep.y = 25;
  1293.  
  1294.     mNextFloatedWndPos.x = mFloatingPosStep.x;
  1295.     mNextFloatedWndPos.y = mFloatingPosStep.y;
  1296. }
  1297.  
  1298. bool wxFrameLayout::HitTestPane( cbDockPane* pPane, int x, int y )
  1299. {
  1300.     return rect_contains_point( pPane->GetRealRect(), x, y );
  1301. }
  1302.  
  1303. cbDockPane* wxFrameLayout::HitTestPanes( const wxRect& rect,
  1304.                                          cbDockPane* pCurPane )
  1305. {
  1306.     // first, give the privilege to the current pane
  1307.  
  1308.     if ( pCurPane && rect_hits_rect( pCurPane->GetRealRect(), rect ) ) 
  1309.     
  1310.         return pCurPane;
  1311.  
  1312.     int i;
  1313.     for ( i = 0; i != MAX_PANES; ++i )
  1314.     {
  1315.         if ( pCurPane != mPanes[i] &&
  1316.              rect_hits_rect( mPanes[i]->GetRealRect(), rect ) ) 
  1317.         {
  1318.             return mPanes[i];
  1319.         }
  1320.     }
  1321.     return 0;
  1322. }
  1323.  
  1324. void wxFrameLayout::ForwardMouseEvent( wxMouseEvent& event, 
  1325.                                            cbDockPane*   pToPane,
  1326.                                            int           eventType )
  1327. {
  1328.     wxPoint pos( event.m_x, event.m_y );
  1329.     pToPane->FrameToPane( &pos.x, &pos.y );
  1330.  
  1331.     if ( eventType == cbEVT_PL_LEFT_DOWN )
  1332.     {
  1333.         cbLeftDownEvent evt( pos, pToPane );
  1334.         FirePluginEvent( evt );
  1335.     }
  1336.     else if ( eventType == cbEVT_PL_LEFT_DCLICK )
  1337.     {
  1338.         cbLeftDClickEvent evt( pos, pToPane );
  1339.         FirePluginEvent( evt );
  1340.     }
  1341.     else if ( eventType == cbEVT_PL_LEFT_UP )
  1342.     {
  1343.         cbLeftUpEvent evt( pos, pToPane );
  1344.         FirePluginEvent( evt );
  1345.     }
  1346.     else if ( eventType == cbEVT_PL_RIGHT_DOWN )
  1347.     {
  1348.         cbRightDownEvent evt( pos, pToPane );
  1349.         FirePluginEvent( evt );
  1350.     }
  1351.     else if ( eventType == cbEVT_PL_RIGHT_UP )
  1352.     {
  1353.         cbRightUpEvent evt( pos, pToPane );
  1354.         FirePluginEvent( evt );
  1355.     }
  1356.     else if ( eventType == cbEVT_PL_MOTION )
  1357.     {
  1358.         cbMotionEvent evt( pos, pToPane );
  1359.         FirePluginEvent( evt );
  1360.     }
  1361.     else 
  1362.     {
  1363.         int avoidCompilerWarning = 0;
  1364.         wxASSERT(avoidCompilerWarning); // DBG::
  1365.     }
  1366. }  // wxFrameLayout::ForwardMouseEvent()
  1367.  
  1368.  
  1369. void wxFrameLayout::RouteMouseEvent( wxMouseEvent& event, int pluginEvtType )
  1370. {
  1371.     if ( mpPaneInFocus )
  1372.  
  1373.         ForwardMouseEvent( event, mpPaneInFocus, pluginEvtType );
  1374.     else
  1375.     {
  1376.         int i;
  1377.         for ( i = 0; i != MAX_PANES; ++i )
  1378.         {
  1379.             if ( HitTestPane( mPanes[i], event.m_x, event.m_y ) )
  1380.             {
  1381.                 ForwardMouseEvent( event, mPanes[i], pluginEvtType );
  1382.                 return;
  1383.             }
  1384.         }
  1385.     }
  1386. }
  1387.  
  1388. /*** event handlers ***/
  1389.  
  1390. void wxFrameLayout::OnRButtonDown( wxMouseEvent& event )
  1391. {
  1392.     RouteMouseEvent( event, cbEVT_PL_RIGHT_DOWN );
  1393. }
  1394.  
  1395. void wxFrameLayout::OnRButtonUp( wxMouseEvent& event )
  1396. {
  1397.     RouteMouseEvent( event, cbEVT_PL_RIGHT_UP );
  1398. }
  1399.  
  1400. void wxFrameLayout::OnLButtonDown( wxMouseEvent& event )
  1401. {
  1402.     RouteMouseEvent( event, cbEVT_PL_LEFT_DOWN );
  1403. }
  1404.  
  1405. void wxFrameLayout::OnLDblClick( wxMouseEvent& event )
  1406. {
  1407.     RouteMouseEvent( event, cbEVT_PL_LEFT_DCLICK );
  1408. }
  1409.  
  1410. void wxFrameLayout::OnLButtonUp( wxMouseEvent& event )
  1411. {
  1412.     RouteMouseEvent( event, cbEVT_PL_LEFT_UP );
  1413. }
  1414.  
  1415. void wxFrameLayout::OnMouseMove( wxMouseEvent& event )
  1416. {
  1417.     if ( mpPaneInFocus )
  1418.     
  1419.         ForwardMouseEvent( event, mpPaneInFocus, cbEVT_PL_MOTION );
  1420.     else
  1421.     {
  1422.         int i;
  1423.         for ( i = 0; i != MAX_PANES; ++i )
  1424.         {
  1425.             if ( HitTestPane( mPanes[i], event.m_x, event.m_y ) )
  1426.             {
  1427.                 if ( mpLRUPane && mpLRUPane != mPanes[i] )
  1428.                 {
  1429.                     // simulate "mouse-leave" event
  1430.                     ForwardMouseEvent( event, mpLRUPane, cbEVT_PL_MOTION );
  1431.                 }
  1432.  
  1433.                 ForwardMouseEvent( event, mPanes[i], cbEVT_PL_MOTION );
  1434.  
  1435.                 mpLRUPane = mPanes[i];
  1436.  
  1437.                 return;
  1438.             }
  1439.         }
  1440.     }
  1441.  
  1442.     if ( mpLRUPane )
  1443.     {
  1444.         // simulate "mouse-leave" event
  1445.         ForwardMouseEvent( event, mpLRUPane, cbEVT_PL_MOTION );
  1446.         mpLRUPane = 0;
  1447.     }
  1448. }
  1449.  
  1450. void wxFrameLayout::OnPaint( wxPaintEvent& event )
  1451. {
  1452.     if ( mRecalcPending  )
  1453.         RecalcLayout( TRUE );
  1454.  
  1455.     wxPaintDC dc(mpFrame);
  1456.  
  1457.     int i;
  1458.     for ( i = 0; i != MAX_PANES; ++i )
  1459.     {
  1460.         wxRect& rect = mPanes[i]->mBoundsInParent;
  1461.  
  1462.         dc.SetClippingRegion( rect.x, rect.y, rect.width, rect.height );
  1463.  
  1464.         mPanes[i]->PaintPane(dc);
  1465.  
  1466.         dc.DestroyClippingRegion();
  1467.     }
  1468.  
  1469.     event.Skip();
  1470. }
  1471.  
  1472. void wxFrameLayout::OnEraseBackground( wxEraseEvent& event )
  1473. {
  1474.     // do nothing
  1475. }
  1476.  
  1477. void wxFrameLayout::OnIdle( wxIdleEvent& event )
  1478. {
  1479.     wxWindow* focus = wxWindow::FindFocus();
  1480.  
  1481.     if ( !focus && mCheckFocusWhenIdle )
  1482.     {
  1483.         wxMessageBox( "Hi, no more focus in this app!" );
  1484.  
  1485.         mCheckFocusWhenIdle = FALSE;
  1486.         //ShowFloatedWindows( FALSE );
  1487.     }
  1488.  
  1489.     mCheckFocusWhenIdle = FALSE;
  1490.  
  1491.     event.Skip();
  1492. }
  1493.  
  1494.  
  1495. void wxFrameLayout::OnKillFocus( wxFocusEvent& event )
  1496. {
  1497.     //wxMessageBox( "wxFrameLayoutGot Kill Focus!" );
  1498.     //ShowFloatedWindows( FALSE );
  1499. }
  1500.  
  1501. void wxFrameLayout::OnSetFocus( wxFocusEvent& event )
  1502. {
  1503.     //ShowFloatedWindows( TRUE );
  1504. }
  1505.  
  1506. void wxFrameLayout::OnActivate( wxActivateEvent& event )
  1507. {
  1508. #if 0
  1509.     if ( event.GetActive() == FALSE )               
  1510.     {
  1511.         wxWindow* focus = wxWindow::FindFocus();
  1512.  
  1513.         if ( !focus || focus == &GetParentFrame() )
  1514.         {
  1515.             mCheckFocusWhenIdle = TRUE;
  1516.  
  1517.             if ( !focus )
  1518.  
  1519.                 wxMessageBox("Deactivated!" );
  1520.  
  1521.         }
  1522.     }
  1523. #endif
  1524. }
  1525.  
  1526. void wxFrameLayout::GetPaneProperties( cbCommonPaneProperties& props, int alignment )
  1527. {
  1528.     props = mPanes[alignment]->mProps;
  1529. }
  1530.  
  1531. void wxFrameLayout::SetPaneProperties( const cbCommonPaneProperties& props, int paneMask )
  1532. {
  1533.     int i;
  1534.     for ( i = 0; i != MAX_PANES; ++i )
  1535.     {
  1536.         if ( mPanes[i]->MatchesMask( paneMask ) )
  1537.             mPanes[i]->mProps = props;
  1538.     }
  1539. }
  1540.  
  1541. void wxFrameLayout::SetMargins( int top, int bottom, int left, int right,
  1542.                                 int paneMask )
  1543. {
  1544.     int i;
  1545.     for ( i = 0; i != MAX_PANES; ++i )
  1546.     {
  1547.         cbDockPane& pane = *mPanes[i];
  1548.  
  1549.         if ( pane.MatchesMask( paneMask ) )
  1550.         {
  1551.             pane.mTopMargin = top;
  1552.             pane.mBottomMargin = bottom;
  1553.             pane.mLeftMargin = left;
  1554.             pane.mRightMargin = right;
  1555.         }
  1556.     }
  1557. }
  1558.  
  1559. void wxFrameLayout::SetPaneBackground( const wxColour& colour )
  1560. {
  1561.     mBorderPen.SetColour( colour );
  1562. }
  1563.  
  1564. void wxFrameLayout::RefreshNow( bool recalcLayout )
  1565. {
  1566.     if ( recalcLayout )
  1567.         RecalcLayout( TRUE );
  1568.  
  1569.     if ( mpFrame )
  1570.         mpFrame->Refresh();
  1571. }
  1572.  
  1573. /*** plugin-related methods ***/
  1574.  
  1575. void wxFrameLayout::FirePluginEvent( cbPluginEvent& event )
  1576. {
  1577.     // check state of input capture, before processing the event
  1578.  
  1579.     if ( mpCaputesInput ) 
  1580.     {
  1581.         bool isInputEvt = TRUE;
  1582. #if wxCHECK_VERSION(2,3,0)
  1583.         if ( event.m_eventType != cbEVT_PL_LEFT_DOWN &&
  1584.              event.m_eventType != cbEVT_PL_LEFT_UP &&
  1585.              event.m_eventType != cbEVT_PL_RIGHT_DOWN &&
  1586.              event.m_eventType != cbEVT_PL_RIGHT_UP &&
  1587.              event.m_eventType != cbEVT_PL_MOTION )
  1588.             isInputEvt = FALSE;
  1589. #else
  1590.         switch ( event.m_eventType )
  1591.         {
  1592.             case cbEVT_PL_LEFT_DOWN  : break;
  1593.             case cbEVT_PL_LEFT_UP    : break;
  1594.             case cbEVT_PL_RIGHT_DOWN : break;
  1595.             case cbEVT_PL_RIGHT_UP   : break;
  1596.             case cbEVT_PL_MOTION     : break;
  1597.             
  1598.             default : isInputEvt = FALSE; break;
  1599.         }
  1600. #endif  // #if wxCHECK_VERSION(2,3,0)
  1601.  
  1602.         if ( isInputEvt )
  1603.         {
  1604.             mpCaputesInput->ProcessEvent( event );
  1605.             return;
  1606.         }
  1607.     }
  1608.  
  1609.     GetTopPlugin().ProcessEvent( event );
  1610. }
  1611.  
  1612. void wxFrameLayout::CaptureEventsForPlugin ( cbPluginBase* pPlugin )
  1613. {
  1614.     // cannot capture events for more than one plugin at a time
  1615.     wxASSERT( mpCaputesInput == NULL );
  1616.  
  1617.     mpCaputesInput = pPlugin;
  1618.  
  1619. }
  1620.  
  1621. void wxFrameLayout::ReleaseEventsFromPlugin( cbPluginBase* pPlugin )
  1622. {
  1623.     // events should be captured first
  1624.     wxASSERT( mpCaputesInput != NULL );
  1625.  
  1626.     mpCaputesInput = NULL;
  1627. }
  1628.  
  1629. void wxFrameLayout::CaptureEventsForPane( cbDockPane* toPane )
  1630. {
  1631.     // cannot capture events twice (without releasing)
  1632.     wxASSERT( mpPaneInFocus == NULL );
  1633.  
  1634.     mpFrame->CaptureMouse();
  1635.  
  1636.     mpPaneInFocus = toPane;
  1637. }
  1638.  
  1639. void wxFrameLayout::ReleaseEventsFromPane( cbDockPane* fromPane )
  1640. {
  1641.     // cannot release events without capturing them
  1642.     wxASSERT( mpPaneInFocus != NULL );
  1643.  
  1644.     mpFrame->ReleaseMouse();
  1645.  
  1646.     mpPaneInFocus = NULL;
  1647. }
  1648.  
  1649. cbPluginBase& wxFrameLayout::GetTopPlugin()
  1650. {
  1651.     if ( !mpTopPlugin ) 
  1652.     
  1653.         PushDefaultPlugins(); // automatic configuration
  1654.  
  1655.     return *mpTopPlugin;
  1656. }
  1657.  
  1658. void wxFrameLayout::SetTopPlugin( cbPluginBase* pPlugin ) 
  1659.     mpTopPlugin = pPlugin; 
  1660. }
  1661.  
  1662. bool wxFrameLayout::HasTopPlugin() 
  1663.     return ( mpTopPlugin != NULL ); 
  1664. }
  1665.  
  1666. void wxFrameLayout::PushPlugin( cbPluginBase* pPlugin )
  1667. {
  1668.     if ( !mpTopPlugin ) 
  1669.         
  1670.         mpTopPlugin = pPlugin;
  1671.     else
  1672.     {
  1673.         pPlugin->SetNextHandler( mpTopPlugin );
  1674.  
  1675.         mpTopPlugin->SetPreviousHandler( pPlugin );
  1676.  
  1677.         mpTopPlugin = pPlugin;
  1678.     }
  1679.  
  1680.     mpTopPlugin->OnInitPlugin(); // notification
  1681. }
  1682.  
  1683. void wxFrameLayout::PopPlugin()
  1684. {
  1685.     wxASSERT( mpTopPlugin ); // DBG:: at least one plugin should be present
  1686.  
  1687.     cbPluginBase* pPopped = mpTopPlugin;
  1688.  
  1689.     mpTopPlugin = (cbPluginBase*)mpTopPlugin->GetNextHandler();
  1690.  
  1691.     delete pPopped;
  1692. }
  1693.  
  1694. void wxFrameLayout::PopAllPlugins()
  1695. {
  1696.     while( mpTopPlugin ) PopPlugin();
  1697. }
  1698.  
  1699. void wxFrameLayout::PushDefaultPlugins()
  1700. {
  1701.     // FIXME:: to much of the stuff for the default...
  1702.  
  1703.     AddPlugin( CLASSINFO( cbRowLayoutPlugin       ) );
  1704.     AddPlugin( CLASSINFO( cbBarDragPlugin         ) );
  1705.     AddPlugin( CLASSINFO( cbPaneDrawPlugin ) );
  1706. }
  1707.  
  1708. void wxFrameLayout::AddPlugin( wxClassInfo* pPlInfo, int paneMask )
  1709. {
  1710.     if ( FindPlugin ( pPlInfo ) ) return; // same type of plugin cannot be added twice
  1711.  
  1712.     cbPluginBase* pObj = (cbPluginBase*)pPlInfo->CreateObject();
  1713.  
  1714.     wxASSERT(pObj); // DBG:: plugin's class should be dynamic
  1715.  
  1716.     pObj->mPaneMask = paneMask;
  1717.     pObj->mpLayout  = this;
  1718.  
  1719.     PushPlugin( pObj );
  1720. }
  1721.  
  1722. void wxFrameLayout::AddPluginBefore( wxClassInfo* pNextPlInfo, wxClassInfo* pPlInfo, 
  1723.                                        int paneMask )
  1724. {
  1725.     wxASSERT( pNextPlInfo != pPlInfo ); // DBG:: no sense
  1726.  
  1727.     cbPluginBase* pNextPl = FindPlugin( pNextPlInfo );
  1728.  
  1729.     if ( !pNextPl )
  1730.     {
  1731.         AddPlugin( pPlInfo, paneMask );
  1732.  
  1733.         return;
  1734.     }
  1735.  
  1736.     // remove existing one if present
  1737.  
  1738.     cbPluginBase* pExistingPl = FindPlugin( pPlInfo );
  1739.     
  1740.     if ( pExistingPl ) RemovePlugin( pPlInfo );
  1741.  
  1742.     // create an instance 
  1743.  
  1744.     cbPluginBase* pNewPl = (cbPluginBase*)pPlInfo->CreateObject();
  1745.  
  1746.     wxASSERT(pNewPl); // DBG:: plugin's class should be dynamic
  1747.  
  1748.     // insert it to the chain
  1749.  
  1750.     if ( pNextPl->GetPreviousHandler() )
  1751.     
  1752.         pNextPl->GetPreviousHandler()->SetNextHandler( pNewPl );
  1753.     else
  1754.         mpTopPlugin = pNewPl;
  1755.  
  1756.     pNewPl->SetNextHandler( pNextPl );
  1757.  
  1758.     pNewPl->SetPreviousHandler( pNextPl->GetPreviousHandler() );
  1759.  
  1760.     pNextPl->SetPreviousHandler( pNewPl );
  1761.  
  1762.     // set it up
  1763.  
  1764.     pNewPl->mPaneMask = paneMask;
  1765.     pNewPl->mpLayout  = this;
  1766.  
  1767.     pNewPl->OnInitPlugin();
  1768. }
  1769.  
  1770. void wxFrameLayout::RemovePlugin( wxClassInfo* pPlInfo )
  1771. {
  1772.     cbPluginBase* pPlugin = FindPlugin( pPlInfo );
  1773.  
  1774.     if ( !pPlugin ) return; // it's OK to remove not-existing plugin ;-)
  1775.  
  1776.     if ( pPlugin->GetPreviousHandler() == NULL )
  1777.  
  1778.         mpTopPlugin = (cbPluginBase*)pPlugin->GetNextHandler();
  1779.  
  1780.     delete pPlugin;
  1781. }
  1782.  
  1783. cbPluginBase* wxFrameLayout::FindPlugin( wxClassInfo* pPlInfo )
  1784. {
  1785.     cbPluginBase *pCur = mpTopPlugin;
  1786.  
  1787.     while( pCur )
  1788.     {
  1789.         // NOTE:: it might appear useful matching plugin
  1790.         //        classes "polymorphically":
  1791.  
  1792.         if ( pCur->GetClassInfo()->IsKindOf( pPlInfo ) )
  1793.  
  1794.             return pCur;
  1795.  
  1796.         pCur = (cbPluginBase*)pCur->GetNextHandler();
  1797.     }
  1798.  
  1799.     return NULL;
  1800. }
  1801.  
  1802. /***** Implementation for class cbUpdateMgrData *****/
  1803.  
  1804. IMPLEMENT_DYNAMIC_CLASS( cbUpdateMgrData, wxObject )
  1805.  
  1806. cbUpdateMgrData::cbUpdateMgrData() 
  1807.  
  1808.     : mPrevBounds( -1,-1,0,0 ),
  1809.       mIsDirty( TRUE )           // inidicate initial change
  1810. {}
  1811.  
  1812. void cbUpdateMgrData::StoreItemState( const wxRect& boundsInParent )
  1813.     mPrevBounds = boundsInParent; 
  1814. }
  1815.  
  1816. void cbUpdateMgrData::SetDirty( bool isDirty )
  1817. {
  1818.     mIsDirty = isDirty;
  1819. }
  1820.  
  1821. void cbUpdateMgrData::SetCustomData( wxObject* pCustomData )
  1822. {
  1823.     mpCustomData = pCustomData;
  1824. }
  1825.  
  1826. /***** Implementation for class cbDockPane *****/
  1827.  
  1828. void wxBarIterator::Reset()
  1829. {
  1830.     mpRow = ( mpRows->Count() ) ? (*mpRows)[0] : NULL;
  1831.     mpBar = NULL;
  1832. }
  1833.  
  1834. wxBarIterator::wxBarIterator( RowArrayT& rows )
  1835.  
  1836.     : mpRows( &rows ),
  1837.       mpRow ( NULL  ),
  1838.       mpBar ( NULL  )
  1839. {
  1840.     Reset();
  1841. }
  1842.  
  1843. bool wxBarIterator::Next()
  1844. {      
  1845.     if ( mpRow )
  1846.     {
  1847.         if ( mpBar )
  1848.             mpBar = mpBar->mpNext;
  1849.         else
  1850.         {
  1851.             if ( mpRow->mBars.GetCount() == 0 )
  1852.             {
  1853.                 return FALSE; 
  1854.             }
  1855.  
  1856.             mpBar = mpRow->mBars[0];
  1857.         }
  1858.     
  1859.         if ( !mpBar )
  1860.         {   
  1861.             // skip to the next row
  1862.  
  1863.             mpRow = mpRow->mpNext;
  1864.     
  1865.             if ( mpRow )
  1866.     
  1867.                 mpBar = mpRow->mBars[0];
  1868.             else
  1869.                 return FALSE;
  1870.         }
  1871.     
  1872.         return TRUE;
  1873.     }
  1874.     else
  1875.         return FALSE;
  1876. }
  1877.  
  1878. cbBarInfo& wxBarIterator::BarInfo()
  1879. {
  1880.     return *mpBar;
  1881. }
  1882.  
  1883. cbRowInfo& wxBarIterator::RowInfo()
  1884. {
  1885.     return *mpRow;
  1886. }
  1887.  
  1888. /***** Implementation for class cbBarDimHandlerBase *****/
  1889.  
  1890. IMPLEMENT_ABSTRACT_CLASS( cbBarDimHandlerBase, wxObject )
  1891.  
  1892. cbBarDimHandlerBase::cbBarDimHandlerBase()
  1893.     : mRefCount(0)
  1894. {}
  1895.  
  1896. void cbBarDimHandlerBase::AddRef()
  1897. {
  1898.     ++mRefCount;
  1899. }
  1900.  
  1901. void cbBarDimHandlerBase::RemoveRef()
  1902. {
  1903.     if ( --mRefCount <= 0 ) delete this;
  1904. }
  1905.  
  1906. /***** Implementation for class cbDimInfo *****/
  1907.  
  1908. IMPLEMENT_DYNAMIC_CLASS( cbDimInfo, wxObject )
  1909.  
  1910. cbDimInfo::cbDimInfo() 
  1911.  
  1912.     : mVertGap ( 0 ), 
  1913.       mHorizGap( 0 ),
  1914.  
  1915.       mIsFixed(TRUE),
  1916.       mpHandler( NULL )
  1917. {
  1918.     size_t i;
  1919.     for ( i = 0; i != MAX_BAR_STATES; ++i )
  1920.     {
  1921.         mSizes[i].x = 20;
  1922.         mSizes[i].y = 20;
  1923.  
  1924.         mBounds[i] = wxRect( -1,-1,-1,-1 );
  1925.     }
  1926. }
  1927.  
  1928. cbDimInfo::cbDimInfo( cbBarDimHandlerBase* pDimHandler,
  1929.                       bool                 isFixed  )
  1930.  
  1931.     : mVertGap ( 0 ),
  1932.       mHorizGap( 0 ),
  1933.       mIsFixed ( isFixed  ),
  1934.  
  1935.       mpHandler( pDimHandler )
  1936. {
  1937.     if ( mpHandler )
  1938.     {
  1939.         // int vtad = *((int*)mpHandler);
  1940.         mpHandler->AddRef();
  1941.     }
  1942.     
  1943.     size_t i;
  1944.     for ( i = 0; i != MAX_BAR_STATES; ++i )
  1945.     {
  1946.         mSizes[i].x = -1;
  1947.         mSizes[i].y = -1;
  1948.  
  1949.         mBounds[i] = wxRect( -1,-1,-1,-1 );
  1950.     }
  1951. }
  1952.  
  1953. cbDimInfo::cbDimInfo( int dh_x, int dh_y,
  1954.                       int dv_x, int dv_y,
  1955.                       int f_x,  int f_y,
  1956.  
  1957.                       bool isFixed,
  1958.                       int horizGap,
  1959.                       int vertGap,
  1960.  
  1961.                       cbBarDimHandlerBase* pDimHandler
  1962.                     )
  1963.     : mVertGap  ( vertGap   ),
  1964.       mHorizGap ( horizGap  ),
  1965.       mIsFixed  ( isFixed   ),
  1966.       mpHandler( pDimHandler )
  1967. {
  1968.     if ( mpHandler )
  1969.     {
  1970.         // int vtad = *((int*)mpHandler);
  1971.         mpHandler->AddRef();
  1972.     }
  1973.  
  1974.     mSizes[wxCBAR_DOCKED_HORIZONTALLY].x = dh_x;
  1975.     mSizes[wxCBAR_DOCKED_HORIZONTALLY].y = dh_y;
  1976.     mSizes[wxCBAR_DOCKED_VERTICALLY  ].x = dv_x;
  1977.     mSizes[wxCBAR_DOCKED_VERTICALLY  ].y = dv_y;
  1978.     mSizes[wxCBAR_FLOATING           ].x = f_x;
  1979.     mSizes[wxCBAR_FLOATING           ].y = f_y;
  1980.  
  1981.     size_t i;
  1982.     for ( i = 0; i != MAX_BAR_STATES; ++i )
  1983.         mBounds[i] = wxRect( -1,-1,-1,-1 );
  1984. }    
  1985.  
  1986. cbDimInfo::cbDimInfo( int x, int y,  
  1987.                       bool isFixed, int gap, 
  1988.                       cbBarDimHandlerBase* pDimHandler)
  1989.   : mVertGap  ( gap ),
  1990.     mHorizGap ( gap ),
  1991.     mIsFixed  ( isFixed ),
  1992.     mpHandler( pDimHandler )
  1993. {
  1994.     if ( mpHandler )
  1995.     {
  1996.         // int vtad = *((int*)mpHandler);
  1997.         mpHandler->AddRef();
  1998.     }
  1999.  
  2000.     mSizes[wxCBAR_DOCKED_HORIZONTALLY].x = x;
  2001.     mSizes[wxCBAR_DOCKED_HORIZONTALLY].y = y;
  2002.     mSizes[wxCBAR_DOCKED_VERTICALLY  ].x = x;
  2003.     mSizes[wxCBAR_DOCKED_VERTICALLY  ].y = y;
  2004.     mSizes[wxCBAR_FLOATING           ].x = x;
  2005.     mSizes[wxCBAR_FLOATING           ].y = y;
  2006.     
  2007.     size_t i;
  2008.     for ( i = 0; i != MAX_BAR_STATES; ++i )
  2009.         mBounds[i] = wxRect( -1,-1,-1,-1 );
  2010. }
  2011.  
  2012. cbDimInfo::~cbDimInfo()
  2013. {
  2014.     if ( mpHandler ) 
  2015.         
  2016.         mpHandler->RemoveRef();
  2017. }
  2018.  
  2019. const cbDimInfo& cbDimInfo::operator=( const cbDimInfo& other )
  2020. {
  2021.     if ( this == &other )
  2022.         return *this;
  2023.  
  2024.     int i;
  2025.     for ( i = 0; i != MAX_BAR_STATES; ++i )
  2026.         mSizes[i] = other.mSizes[i];
  2027.  
  2028.     mIsFixed  = other.mIsFixed;
  2029.     mpHandler = other.mpHandler;
  2030.  
  2031.     mVertGap  = other.mVertGap;
  2032.     mHorizGap = other.mHorizGap;
  2033.  
  2034.     if ( mpHandler )
  2035.  
  2036.         mpHandler->AddRef();
  2037.  
  2038.     return *this;
  2039. }
  2040.  
  2041. /***** Implementation for structure cbCommonPaneProperties *****/
  2042.  
  2043. IMPLEMENT_DYNAMIC_CLASS( cbCommonPaneProperties, wxObject )
  2044.  
  2045. cbCommonPaneProperties::cbCommonPaneProperties(void)
  2046.  
  2047.     : mRealTimeUpdatesOn    ( TRUE  ),
  2048.       mOutOfPaneDragOn      ( TRUE  ),
  2049.       mExactDockPredictionOn( FALSE ),
  2050.       mNonDestructFrictionOn( FALSE ),
  2051.       mShow3DPaneBorderOn   ( TRUE  ),
  2052.       mBarFloatingOn        ( FALSE ),
  2053.       mRowProportionsOn     ( FALSE ),
  2054.       mColProportionsOn     ( TRUE  ),
  2055.       mBarCollapseIconsOn   ( FALSE ),
  2056.       mBarDragHintsOn       ( FALSE ),
  2057.  
  2058.       mMinCBarDim( 16, 16 ),
  2059.       mResizeHandleSize( 4 )
  2060. {}
  2061.  
  2062. cbCommonPaneProperties::cbCommonPaneProperties(const cbCommonPaneProperties& props)
  2063.  
  2064.     : wxObject(),
  2065.       mRealTimeUpdatesOn    (props.mRealTimeUpdatesOn),
  2066.       mOutOfPaneDragOn      (props.mOutOfPaneDragOn),
  2067.       mExactDockPredictionOn(props.mExactDockPredictionOn),
  2068.       mNonDestructFrictionOn(props.mNonDestructFrictionOn),
  2069.       mShow3DPaneBorderOn   (props.mShow3DPaneBorderOn),
  2070.       mBarFloatingOn        (props.mBarFloatingOn),
  2071.       mRowProportionsOn     (props.mRowProportionsOn),
  2072.       mColProportionsOn     (props.mColProportionsOn),
  2073.       mBarCollapseIconsOn   (props.mBarCollapseIconsOn),
  2074.       mBarDragHintsOn       (props.mBarDragHintsOn),
  2075.  
  2076.       mMinCBarDim(props.mMinCBarDim),
  2077.       mResizeHandleSize(props.mResizeHandleSize)
  2078. {}
  2079.  
  2080. cbCommonPaneProperties& cbCommonPaneProperties::operator=(const cbCommonPaneProperties& props)
  2081. {
  2082.     mRealTimeUpdatesOn     = props.mRealTimeUpdatesOn;
  2083.     mOutOfPaneDragOn       = props.mOutOfPaneDragOn;
  2084.     mExactDockPredictionOn = props.mExactDockPredictionOn;
  2085.     mNonDestructFrictionOn = props.mNonDestructFrictionOn;
  2086.     mShow3DPaneBorderOn    = props.mShow3DPaneBorderOn;
  2087.     mBarFloatingOn         = props.mBarFloatingOn;
  2088.     mRowProportionsOn      = props.mRowProportionsOn;
  2089.     mColProportionsOn      = props.mColProportionsOn;
  2090.     mBarCollapseIconsOn    = props.mBarCollapseIconsOn;
  2091.     mBarDragHintsOn        = props.mBarDragHintsOn;
  2092.     
  2093.     mMinCBarDim            = props.mMinCBarDim;
  2094.     mResizeHandleSize      = props.mResizeHandleSize;
  2095.  
  2096.     return *this;
  2097. }
  2098.  
  2099. /***** Implementation for class cbRowInfo *****/
  2100.  
  2101. IMPLEMENT_DYNAMIC_CLASS( cbRowInfo, wxObject )
  2102.  
  2103. cbRowInfo::cbRowInfo(void)
  2104.  
  2105.     : mNotFixedBarsCnt( FALSE ),
  2106.       mpNext          ( NULL ),
  2107.       mpPrev          ( NULL ),
  2108.       mpExpandedBar   ( NULL )
  2109. {}
  2110.  
  2111. cbRowInfo::~cbRowInfo()
  2112. {
  2113.     // nothing! all bars are removed using global bar
  2114.     // list in wxFrameLayout class
  2115. }
  2116.  
  2117. /***** Implementation for class cbBarInfo *****/
  2118.  
  2119. IMPLEMENT_DYNAMIC_CLASS( cbBarInfo, wxObject )
  2120.  
  2121. cbBarInfo::cbBarInfo(void)
  2122.  
  2123.     : mpRow( NULL ),
  2124.  
  2125.       mpNext( NULL ),
  2126.       mpPrev( NULL )
  2127. {}
  2128.  
  2129. cbBarInfo::~cbBarInfo()
  2130. {
  2131.     // nothing
  2132. }
  2133.  
  2134. /***** Implementation for class cbDockPane *****/
  2135.  
  2136. IMPLEMENT_DYNAMIC_CLASS( cbDockPane, wxObject )
  2137.  
  2138. // FIXME:: how to eliminate these cut&pasted constructors?
  2139.  
  2140. cbDockPane::cbDockPane(void)                             
  2141.     : mLeftMargin  ( 1 ),
  2142.       mRightMargin ( 1 ),
  2143.       mTopMargin   ( 1 ),
  2144.       mBottomMargin( 1 ),
  2145.       mPaneWidth ( 32768     ), // fake-up very large pane dims,
  2146.                                 // since the real dimensions of the pane may not 
  2147.                                 // be known, while inserting bars initially
  2148.       mPaneHeight( 32768     ),
  2149.       mAlignment ( -1   ),
  2150.       mpLayout   ( 0 ),
  2151.       mpStoredRow( NULL )
  2152. {}
  2153.  
  2154. cbDockPane::cbDockPane( int alignment, wxFrameLayout* pPanel )
  2155.                              
  2156.     :  mLeftMargin  ( 1 ),
  2157.       mRightMargin ( 1 ),
  2158.       mTopMargin   ( 1 ),
  2159.       mBottomMargin( 1 ),
  2160.       mPaneWidth ( 32768     ), // fake-up very large pane dims,
  2161.                                 // since the real dimensions of the pane may not 
  2162.                                 // be known, while inserting bars initially
  2163.       mPaneHeight( 32768     ),
  2164.       mAlignment ( alignment ),
  2165.       mpLayout   ( pPanel    ),
  2166.       mpStoredRow( NULL )    
  2167. {}
  2168.  
  2169. cbDockPane::~cbDockPane()
  2170. {
  2171.     size_t i;
  2172.     for ( i = 0; i != mRows.Count(); ++i )
  2173.         delete mRows[i];
  2174.  
  2175.     mRowShapeData.DeleteContents( TRUE );
  2176.     
  2177.     // NOTE:: control bar infromation structures are cleaned-up
  2178.     //        in wxFrameLayout's destructor, using global control-bar list
  2179. }
  2180.  
  2181. void cbDockPane::SetMargins( int top, int bottom, int left, int right )
  2182. {
  2183.     mTopMargin    = top;
  2184.     mBottomMargin = bottom;
  2185.     mLeftMargin   = left;
  2186.     mRightMargin  = right;
  2187. }
  2188.  
  2189. /*** helpers of cbDockPane ***/
  2190.  
  2191. void cbDockPane::PaintBarDecorations( cbBarInfo* pBar, wxDC& dc )
  2192. {
  2193.     cbDrawBarDecorEvent evt( pBar, dc, this );
  2194.  
  2195.     mpLayout->FirePluginEvent( evt );
  2196. }
  2197.  
  2198. void cbDockPane::PaintBarHandles( cbBarInfo* pBar, wxDC& dc )
  2199. {
  2200.     cbDrawBarHandlesEvent evt( pBar, dc, this );
  2201.  
  2202.     mpLayout->FirePluginEvent( evt );
  2203. }
  2204.  
  2205. void cbDockPane::PaintBar( cbBarInfo* pBar, wxDC& dc )
  2206. {
  2207.     PaintBarDecorations( pBar, dc );
  2208.     PaintBarHandles( pBar, dc );
  2209. }
  2210.  
  2211. void cbDockPane::PaintRowHandles( cbRowInfo* pRow, wxDC& dc )
  2212. {
  2213.     cbDrawRowHandlesEvent evt( pRow, dc, this );
  2214.  
  2215.     mpLayout->FirePluginEvent( evt );
  2216.  
  2217.     cbDrawRowDecorEvent evt1( pRow, dc, this );
  2218.  
  2219.     mpLayout->FirePluginEvent( evt1 );
  2220. }
  2221.  
  2222. void cbDockPane::PaintRowBackground ( cbRowInfo* pRow, wxDC& dc )
  2223. {
  2224.     cbDrawRowBkGroundEvent evt( pRow, dc, this );
  2225.  
  2226.     mpLayout->FirePluginEvent( evt );
  2227. }
  2228.  
  2229. void cbDockPane::PaintRowDecorations( cbRowInfo* pRow, wxDC& dc )
  2230. {
  2231.     size_t i = 0;
  2232.  
  2233.     // decorations first
  2234.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  2235.     
  2236.         PaintBarDecorations( pRow->mBars[i], dc );
  2237.  
  2238.     // then handles if present
  2239.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  2240.  
  2241.         PaintBarHandles( pRow->mBars[i], dc );
  2242. }
  2243.  
  2244. void cbDockPane::PaintRow( cbRowInfo* pRow, wxDC& dc )
  2245. {
  2246.     PaintRowBackground ( pRow, dc );
  2247.     PaintRowDecorations( pRow, dc );
  2248.     PaintRowHandles    ( pRow, dc );
  2249. }
  2250.  
  2251. void cbDockPane::PaintPaneBackground( wxDC& dc )
  2252. {
  2253.     cbDrawPaneBkGroundEvent evt( dc, this );
  2254.  
  2255.     mpLayout->FirePluginEvent( evt );
  2256. }
  2257.  
  2258. void cbDockPane::PaintPaneDecorations( wxDC& dc )
  2259. {
  2260.     cbDrawPaneDecorEvent evt( dc, this );
  2261.  
  2262.     mpLayout->FirePluginEvent( evt );
  2263. }
  2264.  
  2265. void cbDockPane::PaintPane( wxDC& dc )
  2266. {
  2267.     PaintPaneBackground( dc );
  2268.  
  2269.     size_t i = 0;
  2270.  
  2271.     // first decorations
  2272.     for ( i = 0; i != mRows.Count(); ++i )
  2273.     {
  2274.         PaintRowBackground( mRows[i], dc );
  2275.         PaintRowDecorations( mRows[i], dc );
  2276.     }
  2277.  
  2278.     // than handles
  2279.     for ( i = 0; i != mRows.Count(); ++i )
  2280.         PaintRowHandles( mRows[i], dc );
  2281.  
  2282.     // and finally
  2283.     PaintPaneDecorations( dc );
  2284. }
  2285.  
  2286. void cbDockPane::SizeBar( cbBarInfo* pBar )
  2287. {
  2288.     cbSizeBarWndEvent evt( pBar, this );
  2289.  
  2290.     mpLayout->FirePluginEvent( evt );
  2291.     return;
  2292. }
  2293.  
  2294. void cbDockPane::SizeRowObjects( cbRowInfo* pRow )
  2295. {
  2296.     size_t i;
  2297.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  2298.         SizeBar( pRow->mBars[i] );
  2299. }
  2300.  
  2301. void cbDockPane::SizePaneObjects()
  2302. {
  2303.     size_t i;
  2304.     for ( i = 0; i != mRows.Count(); ++i )
  2305.         SizeRowObjects( mRows[i] );
  2306. }
  2307.  
  2308. wxDC* cbDockPane::StartDrawInArea( const wxRect& area )
  2309. {
  2310.     wxDC* pDc = 0;
  2311.  
  2312.     cbStartDrawInAreaEvent evt( area, &pDc, this );
  2313.  
  2314.     mpLayout->FirePluginEvent( evt );
  2315.  
  2316.     return pDc;
  2317. }
  2318.  
  2319. void cbDockPane::FinishDrawInArea( const wxRect& area )
  2320. {
  2321.     cbFinishDrawInAreaEvent evt( area, this );
  2322.  
  2323.     mpLayout->FirePluginEvent( evt );
  2324. }
  2325.  
  2326. bool cbDockPane::IsFixedSize( cbBarInfo* pInfo )
  2327. {
  2328.     return ( pInfo->mDimInfo.mIsFixed );
  2329. }
  2330.  
  2331. int cbDockPane::GetNotFixedBarsCount( cbRowInfo* pRow )
  2332. {
  2333.     int cnt = 0;
  2334.  
  2335.     size_t i;
  2336.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  2337.     {
  2338.         if ( !pRow->mBars[i]->IsFixed() )
  2339.             ++cnt;
  2340.     }
  2341.  
  2342.     return cnt;
  2343. }
  2344.  
  2345. void cbDockPane::RemoveBar( cbBarInfo* pBar )
  2346. {
  2347.     bool needsRestoring = mProps.mNonDestructFrictionOn && 
  2348.                           mpStoredRow == pBar->mpRow;
  2349.  
  2350.     cbRemoveBarEvent evt( pBar, this );
  2351.  
  2352.     mpLayout->FirePluginEvent( evt );
  2353.  
  2354.     if ( needsRestoring )
  2355.     {
  2356.         SetRowShapeData( mpStoredRow, &mRowShapeData );
  2357.  
  2358.         mpStoredRow = NULL;
  2359.     }
  2360. }
  2361.  
  2362. void cbDockPane::SyncRowFlags( cbRowInfo* pRow )
  2363. {
  2364.     // setup mHasOnlyFixedBars flag for the row information
  2365.     pRow->mHasOnlyFixedBars = TRUE;
  2366.  
  2367.     pRow->mNotFixedBarsCnt = 0;
  2368.  
  2369.     size_t i;
  2370.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  2371.     {
  2372.         cbBarInfo& bar = *pRow->mBars[i];
  2373.  
  2374.         bar.mpRow = pRow;
  2375.  
  2376.         if ( !bar.IsFixed() )
  2377.         {
  2378.             pRow->mHasOnlyFixedBars = FALSE;
  2379.             ++pRow->mNotFixedBarsCnt;
  2380.         }
  2381.     }
  2382. }
  2383.  
  2384. void cbDockPane::FrameToPane( int* x, int* y )
  2385. {
  2386.     *x -= mLeftMargin;
  2387.     *y -= mTopMargin;
  2388.  
  2389.     if ( mAlignment == FL_ALIGN_TOP ||
  2390.          mAlignment == FL_ALIGN_BOTTOM 
  2391.        )
  2392.     {
  2393.         *x -= mBoundsInParent.x;
  2394.         *y -= mBoundsInParent.y;
  2395.     }
  2396.     else
  2397.     {
  2398.         int rx = *x, ry = *y;
  2399.  
  2400.         *x = ry - mBoundsInParent.y;
  2401.  
  2402.         *y = rx - mBoundsInParent.x;
  2403.     }
  2404. }
  2405.  
  2406. void cbDockPane::PaneToFrame( int* x, int* y )
  2407. {
  2408.     if ( mAlignment == FL_ALIGN_TOP ||
  2409.          mAlignment == FL_ALIGN_BOTTOM 
  2410.        )
  2411.     {
  2412.         *x += mBoundsInParent.x;
  2413.         *y += mBoundsInParent.y;
  2414.     }
  2415.     else
  2416.     {
  2417.         int rx = *x, ry = *y;
  2418.  
  2419.         *x = ry + mBoundsInParent.x;
  2420.  
  2421.         *y = mBoundsInParent.y + rx;
  2422.     }
  2423.  
  2424.     *x += mLeftMargin;
  2425.     *y += mTopMargin;
  2426. }
  2427.  
  2428. void cbDockPane::FrameToPane( wxRect* pRect )
  2429. {
  2430.     wxPoint upperLeft ( pRect->x, pRect->y );
  2431.     wxPoint lowerRight( pRect->x + pRect->width,
  2432.                         pRect->y + pRect->height );
  2433.  
  2434.     FrameToPane( &upperLeft.x,  &upperLeft.y  );
  2435.     FrameToPane( &lowerRight.x, &lowerRight.y );
  2436.  
  2437.     pRect->x = wxMin(upperLeft.x,lowerRight.x);
  2438.     pRect->y = wxMin(upperLeft.y,lowerRight.y);
  2439.  
  2440.     pRect->width  = abs( lowerRight.x - upperLeft.x );
  2441.     pRect->height = abs( lowerRight.y - upperLeft.y );
  2442. }
  2443.  
  2444. void cbDockPane::PaneToFrame( wxRect* pRect )
  2445. {
  2446.     wxPoint upperLeft ( pRect->x, pRect->y );
  2447.     wxPoint lowerRight( pRect->x + pRect->width,
  2448.                         pRect->y + pRect->height );
  2449.  
  2450.     PaneToFrame( &upperLeft.x,  &upperLeft.y  );
  2451.     PaneToFrame( &lowerRight.x, &lowerRight.y );
  2452.  
  2453.     //wxRect newRect = wxRect( upperLeft, lowerRight );
  2454.  
  2455.     pRect->x = wxMin(upperLeft.x,lowerRight.x);
  2456.     pRect->y = wxMin(upperLeft.y,lowerRight.y);
  2457.  
  2458.     pRect->width  = abs( lowerRight.x - upperLeft.x );
  2459.     pRect->height = abs( lowerRight.y - upperLeft.y );
  2460. }
  2461.  
  2462. int cbDockPane::GetRowAt( int paneY )
  2463. {
  2464.     if ( paneY < 0 )
  2465.         return -1;
  2466.  
  2467.     int curY = 0;
  2468.  
  2469.     size_t i = 0;
  2470.  
  2471.     for ( ; i != mRows.Count(); ++i )
  2472.     {
  2473.         int rowHeight = mRows[i]->mRowHeight;
  2474.  
  2475.         int third = rowHeight/3;
  2476.         
  2477.         if ( paneY >= curY && paneY < curY + third ) 
  2478.             return i-1;
  2479.  
  2480.         if ( paneY >= curY + third && paneY < curY + rowHeight - third ) 
  2481.             return i;
  2482.  
  2483.         curY += rowHeight;
  2484.     }
  2485.  
  2486.     return i;
  2487. }
  2488.  
  2489. int cbDockPane::GetRowAt( int upperY, int lowerY )
  2490. {
  2491.     /*
  2492.     // OLD STUFF::
  2493.     int range    = lowerY - upperY;
  2494.     int oneThird = range / 3;
  2495.  
  2496.     wxNode* pRow = mRows.First();
  2497.     int row = 0;
  2498.     int curY = 0;
  2499.  
  2500.     if ( lowerY <= 0 ) return -1;
  2501.  
  2502.     while( pRow )
  2503.     {
  2504.         int rowHeight = GetRowHeight( (wxList*)pRow->Data() );
  2505.  
  2506.         if ( upperY >= curY &&
  2507.              lowerY < curY ) return row;
  2508.  
  2509.         if ( upperY <= curY && 
  2510.              lowerY >= curY &&
  2511.              curY - upperY >= oneThird ) return row-1;
  2512.  
  2513.         if ( ( upperY <  curY + rowHeight && 
  2514.                lowerY >= curY + rowHeight &&
  2515.                curY + rowHeight - lowerY >= oneThird ) 
  2516.            )
  2517.             return row+1;
  2518.  
  2519.         if ( lowerY <= curY + rowHeight ) return row;
  2520.  
  2521.         ++row;
  2522.         curY += rowHeight;
  2523.         pRow = pRow->Next();
  2524.     }
  2525.     */
  2526.  
  2527.     int mid = upperY + (lowerY - upperY)/2;
  2528.  
  2529.     if ( mid < 0 )
  2530.         return -1;
  2531.  
  2532.     int curY = 0;
  2533.     size_t i = 0;
  2534.  
  2535.     for ( ; i != mRows.Count(); ++i )
  2536.     {
  2537.         int rowHeight = mRows[i]->mRowHeight;
  2538.  
  2539.         if ( mid >= curY && mid < curY + rowHeight ) return i;
  2540.  
  2541.         curY += rowHeight;
  2542.     }
  2543.  
  2544.     return i;
  2545. }
  2546.  
  2547. int cbDockPane::GetRowY( cbRowInfo* pRow )
  2548. {
  2549.     int curY = 0;
  2550.  
  2551.     size_t i;
  2552.     for ( i = 0; i != mRows.Count(); ++i )
  2553.     {
  2554.         if ( mRows[i] == pRow )
  2555.             break;
  2556.  
  2557.         curY += mRows[i]->mRowHeight;
  2558.     }
  2559.  
  2560.     return curY;
  2561. }
  2562.  
  2563. bool cbDockPane::HasNotFixedRowsAbove( cbRowInfo* pRow )
  2564. {
  2565.     while ( pRow->mpPrev )
  2566.     {
  2567.         pRow = pRow->mpPrev;
  2568.  
  2569.         if ( pRow->mHasOnlyFixedBars )
  2570.  
  2571.             return TRUE;
  2572.     } 
  2573.  
  2574.     return FALSE;
  2575. }
  2576.  
  2577. bool cbDockPane::HasNotFixedRowsBelow( cbRowInfo* pRow )
  2578. {
  2579.     while( pRow->mpNext )
  2580.     {
  2581.         pRow = pRow->mpNext;
  2582.  
  2583.         if ( pRow->mHasOnlyFixedBars )
  2584.  
  2585.             return TRUE;
  2586.     }
  2587.  
  2588.     return FALSE;
  2589. }
  2590.  
  2591. bool cbDockPane::HasNotFixedBarsLeft( cbBarInfo* pBar )
  2592. {
  2593.     while( pBar->mpPrev )
  2594.     {
  2595.         pBar = pBar->mpPrev;
  2596.  
  2597.         if ( pBar->IsFixed() )
  2598.  
  2599.             return TRUE;
  2600.     }
  2601.         
  2602.     return FALSE;
  2603. }
  2604.  
  2605. bool cbDockPane::HasNotFixedBarsRight( cbBarInfo* pBar )
  2606. {
  2607.     while( pBar->mpNext )
  2608.     {
  2609.         pBar = pBar->mpNext;
  2610.  
  2611.         if ( pBar->IsFixed() )
  2612.  
  2613.             return TRUE;
  2614.     }
  2615.         
  2616.     return FALSE;
  2617. }
  2618.  
  2619. void cbDockPane::CalcLengthRatios( cbRowInfo* pInRow )
  2620. {
  2621.     int totalWidth = 0;
  2622.  
  2623.     size_t i = 0;
  2624.  
  2625.     // calc current-maximal-total-length of all maximized bars
  2626.  
  2627.     for ( i = 0; i != pInRow->mBars.GetCount(); ++i )
  2628.     {
  2629.         cbBarInfo& bar = *pInRow->mBars[i];
  2630.  
  2631.         if ( !bar.IsFixed() )
  2632.             totalWidth += bar.mBounds.width;
  2633.     }
  2634.  
  2635.     // set up percentages of occupied space for each maximized bar
  2636.  
  2637.     for ( i = 0; i != pInRow->mBars.Count(); ++i )
  2638.     {
  2639.         cbBarInfo& bar = *pInRow->mBars[i];
  2640.  
  2641.         if ( !bar.IsFixed() )
  2642.             bar.mLenRatio = double(bar.mBounds.width)/double(totalWidth);
  2643.     }
  2644. }
  2645.  
  2646. void cbDockPane::RecalcRowLayout( cbRowInfo* pRow )
  2647. {
  2648.     cbLayoutRowEvent evt( pRow, this );
  2649.     
  2650.     mpLayout->FirePluginEvent( evt );
  2651. }
  2652.  
  2653. void cbDockPane::ExpandBar( cbBarInfo* pBar )
  2654. {
  2655.     mpLayout->GetUpdatesManager().OnStartChanges();
  2656.  
  2657.     if ( !pBar->mpRow->mpExpandedBar )
  2658.     {
  2659.         // save ratios only when there arent any bars expanded yet
  2660.  
  2661.         cbArrayFloat& ratios = pBar->mpRow->mSavedRatios;
  2662.  
  2663.         ratios.Clear();
  2664.         ratios.Alloc( pBar->mpRow->mNotFixedBarsCnt );
  2665.  
  2666.         cbBarInfo* pCur = pBar->mpRow->mBars[0];
  2667.  
  2668.         while( pCur )
  2669.         {
  2670.             if ( !pCur->IsFixed() )
  2671.             {
  2672.                 ratios.Add( 0.0 );
  2673.                 ratios[ ratios.GetCount() - 1 ] = pCur->mLenRatio; 
  2674.             }
  2675.  
  2676.             pCur = pCur->mpNext;
  2677.         }
  2678.     }
  2679.  
  2680.     cbBarInfo* pCur = pBar->mpRow->mBars[0];
  2681.  
  2682.     while( pCur )
  2683.     {
  2684.         pCur->mLenRatio = 0.0; // minimize the rest
  2685.  
  2686.         pCur = pCur->mpNext;
  2687.     }
  2688.  
  2689.     pBar->mLenRatio     = 1.0; // 100%
  2690.     pBar->mBounds.width = 0;
  2691.  
  2692.     pBar->mpRow->mpExpandedBar = pBar;
  2693.  
  2694.     mpLayout->RecalcLayout( FALSE );
  2695.  
  2696.     mpLayout->GetUpdatesManager().OnFinishChanges();
  2697.     mpLayout->GetUpdatesManager().UpdateNow();
  2698. }
  2699.  
  2700. void cbDockPane::ContractBar( cbBarInfo* pBar )
  2701. {
  2702.     mpLayout->GetUpdatesManager().OnStartChanges();
  2703.  
  2704.     // FIXME: What's the purpose of this???
  2705.     // double ratio = 1.0/ double( pBar->mpRow->mNotFixedBarsCnt );
  2706.  
  2707.     // restore ratios which were present before expansion
  2708.  
  2709.     cbBarInfo* pCur = pBar->mpRow->mBars[0];
  2710.  
  2711.     cbArrayFloat& ratios = pBar->mpRow->mSavedRatios;
  2712.  
  2713.     size_t i = 0;
  2714.  
  2715.     while( pCur )
  2716.     {
  2717.         if ( !pCur->IsFixed() )
  2718.         {
  2719.             pCur->mLenRatio = ratios[i];
  2720.             ++i;
  2721.         }
  2722.  
  2723.         pCur = pCur->mpNext;
  2724.     }
  2725.  
  2726.     ratios.Clear();
  2727.     ratios.Shrink();
  2728.  
  2729.     pBar->mpRow->mpExpandedBar = NULL;
  2730.  
  2731.     mpLayout->RecalcLayout( FALSE );
  2732.  
  2733.     mpLayout->GetUpdatesManager().OnFinishChanges();
  2734.     mpLayout->GetUpdatesManager().UpdateNow();
  2735. }
  2736.  
  2737. void cbDockPane::InitLinksForRow( cbRowInfo* pRow )
  2738. {
  2739.     size_t i;
  2740.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  2741.     {
  2742.         cbBarInfo& bar = *pRow->mBars[i];
  2743.  
  2744.         if ( i == 0 )
  2745.             bar.mpPrev = NULL;
  2746.         else
  2747.             bar.mpPrev = pRow->mBars[i-1];
  2748.  
  2749.         if ( i == pRow->mBars.Count() - 1 )
  2750.             bar.mpNext = NULL;
  2751.         else
  2752.             bar.mpNext = pRow->mBars[i+1];
  2753.     }
  2754. }
  2755.  
  2756. void cbDockPane::InitLinksForRows()
  2757. {
  2758.     size_t i;
  2759.     for ( i = 0; i != mRows.Count(); ++i )
  2760.     {
  2761.         cbRowInfo& row = *mRows[i];
  2762.  
  2763.         if ( i == 0 )
  2764.             row.mpPrev = NULL;
  2765.         else
  2766.             row.mpPrev = mRows[i-1];
  2767.  
  2768.         if ( i == mRows.Count() - 1 )
  2769.             row.mpNext = NULL;
  2770.         else
  2771.             row.mpNext = mRows[i+1];
  2772.     }
  2773. }
  2774.  
  2775. void cbDockPane::DoInsertBar( cbBarInfo* pBar, int rowNo )
  2776. {
  2777.     cbRowInfo* pRow = NULL;
  2778.  
  2779.     if ( rowNo == -1 || rowNo >= (int)mRows.Count() )
  2780.     {
  2781.         pRow = new cbRowInfo();
  2782.  
  2783.         if ( rowNo == -1 && mRows.Count() )
  2784.         
  2785.             mRows.Insert( pRow, 0 ); 
  2786.         else
  2787.             mRows.Add( pRow );
  2788.  
  2789.         InitLinksForRows();
  2790.     }
  2791.     else
  2792.     {
  2793.         pRow = mRows[rowNo];
  2794.  
  2795.         if ( mProps.mNonDestructFrictionOn == TRUE )
  2796.         {
  2797.             // store original shape of the row (before the bar is inserted)
  2798.  
  2799.             mpStoredRow = pRow;
  2800.             
  2801.             GetRowShapeData( mpStoredRow, &mRowShapeData );
  2802.         }
  2803.     }
  2804.  
  2805.     if ( pRow->mBars.Count() )
  2806.  
  2807.         pRow->mpExpandedBar = NULL;
  2808.  
  2809.     cbInsertBarEvent insEvt( pBar, pRow, this );
  2810.  
  2811.     mpLayout->FirePluginEvent( insEvt );
  2812.  
  2813.     mpLayout->GetUpdatesManager().OnRowWillChange( pRow, this );
  2814. }
  2815.  
  2816. void cbDockPane::InsertBar( cbBarInfo* pBarInfo, const wxRect& atRect )
  2817. {
  2818.     wxRect rect = atRect;
  2819.     FrameToPane( &rect );
  2820.  
  2821.     pBarInfo->mBounds.x      = rect.x;
  2822.     pBarInfo->mBounds.width  = rect.width;
  2823.     pBarInfo->mBounds.height = rect.height;
  2824.  
  2825.     int row = GetRowAt( rect.y, rect.y + rect.height );
  2826.  
  2827.     DoInsertBar( pBarInfo, row );
  2828. }
  2829.  
  2830. void cbDockPane::InsertBar( cbBarInfo* pBar, cbRowInfo* pIntoRow )
  2831. {
  2832.     cbInsertBarEvent insEvt( pBar, pIntoRow, this );
  2833.  
  2834.     mpLayout->FirePluginEvent( insEvt );
  2835.  
  2836.     mpLayout->GetUpdatesManager().OnRowWillChange( pIntoRow, this );
  2837. }
  2838.  
  2839. void cbDockPane::InsertBar( cbBarInfo* pBarInfo )
  2840. {
  2841.     // set transient properties
  2842.  
  2843.     pBarInfo->mpRow           = NULL;
  2844.     pBarInfo->mHasLeftHandle  = FALSE;
  2845.     pBarInfo->mHasRightHandle = FALSE;
  2846.     pBarInfo->mLenRatio       = 0.0;
  2847.  
  2848.     // set preferred bar dimensions, according to the state in which
  2849.     // the bar is being inserted
  2850.  
  2851.     pBarInfo->mBounds.width   = pBarInfo->mDimInfo.mSizes[ pBarInfo->mState ].x;
  2852.     pBarInfo->mBounds.height  = pBarInfo->mDimInfo.mSizes[ pBarInfo->mState ].y;
  2853.  
  2854.     DoInsertBar( pBarInfo, pBarInfo->mRowNo );
  2855. }
  2856.  
  2857. void cbDockPane::RemoveRow( cbRowInfo* pRow )
  2858. {
  2859.     size_t i;
  2860.     // first, hide all bar-windows in the removed row
  2861.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  2862.     {
  2863.         if ( pRow->mBars[i]->mpBarWnd )
  2864.             pRow->mBars[i]->mpBarWnd->Show( FALSE );
  2865.     }
  2866.  
  2867.     mRows.Remove( pRow );
  2868.  
  2869.     pRow->mUMgrData.SetDirty(TRUE);
  2870. }
  2871.  
  2872. void cbDockPane::InsertRow( cbRowInfo* pRow, cbRowInfo* pBeforeRow )
  2873. {
  2874.     if ( !pBeforeRow )
  2875.  
  2876.         mRows.Add( pRow );
  2877.     else
  2878.         mRows.Insert( pRow, mRows.Index( pBeforeRow ) );
  2879.  
  2880.     InitLinksForRows();
  2881.  
  2882.     pRow->mUMgrData.SetDirty(TRUE);
  2883.  
  2884.     size_t i;
  2885.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  2886.         pRow->mBars[i]->mUMgrData.SetDirty( TRUE );
  2887.  
  2888.     SyncRowFlags( pRow );
  2889. }
  2890.  
  2891. void cbDockPane::SetPaneWidth(int width)
  2892. {
  2893.     if ( IsHorizontal() )
  2894.         mPaneWidth = width - mLeftMargin - mRightMargin;
  2895.     else
  2896.         mPaneWidth = width - mTopMargin - mBottomMargin;
  2897. }
  2898.  
  2899.  
  2900. void cbDockPane::SetBoundsInParent( const wxRect& rect )
  2901. {
  2902.     mBoundsInParent = rect;
  2903.  
  2904.     // set pane dimensions in local coordinates
  2905.  
  2906.     if ( IsHorizontal() )
  2907.     {
  2908.         mPaneWidth  = mBoundsInParent.width  - ( mRightMargin + mLeftMargin   );
  2909.         mPaneHeight = mBoundsInParent.height - ( mTopMargin   + mBottomMargin );
  2910.     }
  2911.     else
  2912.     {
  2913.         mPaneWidth  = mBoundsInParent.height - ( mTopMargin   + mBottomMargin );
  2914.         mPaneHeight = mBoundsInParent.width  - ( mRightMargin + mLeftMargin   );
  2915.     }
  2916.  
  2917.     // convert bounding rectangles of all pane items into parent frame's coordinates
  2918.  
  2919.     wxBarIterator i( mRows );
  2920.  
  2921.     wxRect noMarginsRect = mBoundsInParent;
  2922.  
  2923.     noMarginsRect.x      += mLeftMargin;
  2924.     noMarginsRect.y      += mTopMargin;
  2925.     noMarginsRect.width  -= ( mLeftMargin + mRightMargin  );
  2926.     noMarginsRect.height -= ( mTopMargin  + mBottomMargin );
  2927.  
  2928.     // hide the whole pane, if it's bounds became reverted (i.e. pane vanished)
  2929.  
  2930.     if ( mBoundsInParent.width < 0 ||
  2931.          mBoundsInParent.height < 0 )
  2932.  
  2933.          hide_rect( mBoundsInParent );
  2934.  
  2935.     if ( noMarginsRect.width < 0 ||
  2936.          noMarginsRect.height < 0 )
  2937.     
  2938.         hide_rect( noMarginsRect   );
  2939.  
  2940.     // calculate mBoundsInParent for each item in the pane
  2941.  
  2942.     while( i.Next() )
  2943.     {
  2944.         cbBarInfo& bar = i.BarInfo();
  2945.  
  2946.         cbRowInfo* pRowInfo = bar.mpRow;
  2947.  
  2948.         // set up row info, if this is first bar in the row
  2949.  
  2950.         if ( pRowInfo && bar.mpPrev == NULL )
  2951.         {
  2952.             pRowInfo->mBoundsInParent.y      = pRowInfo->mRowY;
  2953.             pRowInfo->mBoundsInParent.x      = 0;
  2954.             pRowInfo->mBoundsInParent.width  = mPaneWidth;
  2955.             pRowInfo->mBoundsInParent.height = pRowInfo->mRowHeight;
  2956.  
  2957.             PaneToFrame( &pRowInfo->mBoundsInParent );
  2958.  
  2959.             clip_rect_against_rect( pRowInfo->mBoundsInParent, noMarginsRect );
  2960.         }
  2961.  
  2962.         wxRect bounds = bar.mBounds;
  2963.  
  2964.         // exclude dimensions of handles, when calculating
  2965.         // bar's bounds in parent (i.e. "visual bounds")
  2966.  
  2967.         if ( bar.mHasLeftHandle )
  2968.         {
  2969.             bounds.x     += mProps.mResizeHandleSize;
  2970.             bounds.width -= mProps.mResizeHandleSize;
  2971.         }
  2972.  
  2973.         if ( bar.mHasRightHandle )
  2974.         
  2975.             bounds.width -= mProps.mResizeHandleSize;
  2976.  
  2977.         PaneToFrame( &bounds );
  2978.  
  2979.         clip_rect_against_rect( bounds, noMarginsRect );
  2980.  
  2981.         bar.mBoundsInParent = bounds;
  2982.     }
  2983. }
  2984.  
  2985. bool cbDockPane::BarPresent( cbBarInfo* pBar )
  2986. {
  2987.     wxBarIterator iter( mRows );
  2988.  
  2989.     while( iter.Next() )
  2990.     
  2991.         if ( &iter.BarInfo() == pBar ) return TRUE;
  2992.  
  2993.     return FALSE;
  2994. }
  2995.  
  2996. cbRowInfo* cbDockPane::GetRow( int row )
  2997. {
  2998.     if ( row >= (int)mRows.Count() ) return NULL;
  2999.  
  3000.     return mRows[ row ];
  3001. }
  3002.  
  3003. int cbDockPane::GetRowIndex( cbRowInfo* pRow )
  3004. {
  3005.     size_t i;
  3006.     for ( i = 0; i != mRows.Count(); ++i )
  3007.     {
  3008.         if ( mRows[i] == pRow ) 
  3009.             return i;
  3010.     }
  3011.  
  3012.     wxFAIL_MSG("Row must be present to call cbDockPane::GetRowIndex()");
  3013.  
  3014.     return 0;
  3015. }
  3016.  
  3017. int cbDockPane::GetPaneHeight()
  3018. {
  3019.     // first, recalculate row heights and the Y-positions
  3020.  
  3021.     cbLayoutRowsEvent evt( this );
  3022.     mpLayout->FirePluginEvent( evt );
  3023.  
  3024.     int height = 0;
  3025.  
  3026.     if ( IsHorizontal() )
  3027.     
  3028.         height += mTopMargin  + mBottomMargin;
  3029.     else
  3030.         height += mLeftMargin + mRightMargin;
  3031.  
  3032.     int count = mRows.Count();
  3033.  
  3034.     if ( count )
  3035.     
  3036.         height += mRows[count-1]->mRowY + mRows[count-1]->mRowHeight;
  3037.  
  3038.     return height;
  3039. }
  3040.  
  3041. int cbDockPane::GetAlignment()
  3042. {
  3043.     return mAlignment;
  3044. }
  3045.  
  3046. bool cbDockPane::MatchesMask( int paneMask )
  3047. {
  3048.     int thisMask = 0;
  3049.  
  3050.     // FIXME:: use array instead of switch()
  3051.  
  3052.     switch (mAlignment)
  3053.     {
  3054.         case FL_ALIGN_TOP    : thisMask = FL_ALIGN_TOP_PANE;   break;
  3055.         case FL_ALIGN_BOTTOM : thisMask = FL_ALIGN_BOTTOM_PANE;break;
  3056.         case FL_ALIGN_LEFT   : thisMask = FL_ALIGN_LEFT_PANE;  break;
  3057.         case FL_ALIGN_RIGHT  : thisMask = FL_ALIGN_RIGHT_PANE; break;
  3058.  
  3059.         default:
  3060.             wxFAIL_MSG("Bad FL alignment type detected in cbDockPane::MatchesMask()");
  3061.     }
  3062.  
  3063.     return ( thisMask & paneMask ) != 0;
  3064. }
  3065.  
  3066. void cbDockPane::RecalcLayout()
  3067. {
  3068.     // first, reposition rows and items vertically
  3069.  
  3070.     cbLayoutRowsEvent evt( this );
  3071.     mpLayout->FirePluginEvent( evt );
  3072.  
  3073.     // then horizontally in each row 
  3074.  
  3075.     size_t i;
  3076.     for ( i = 0; i != mRows.Count(); ++i )
  3077.         RecalcRowLayout( mRows[i] );
  3078. }
  3079.  
  3080. int cbDockPane::GetDockingState()
  3081. {
  3082.     if ( mAlignment == FL_ALIGN_TOP || 
  3083.          mAlignment == FL_ALIGN_BOTTOM )
  3084.     {
  3085.         return wxCBAR_DOCKED_HORIZONTALLY;
  3086.     }
  3087.     else
  3088.         return wxCBAR_DOCKED_VERTICALLY;
  3089. }
  3090.  
  3091. inline bool cbDockPane::HasPoint( const wxPoint& pos, int x, int y, 
  3092.                                   int width, int height )
  3093. {
  3094.     return ( pos.x >= x && 
  3095.              pos.y >= y &&
  3096.              pos.x < x + width &&
  3097.              pos.y < y + height   );
  3098. }
  3099.  
  3100. int cbDockPane::HitTestPaneItems( const wxPoint& pos,
  3101.                                   cbRowInfo**    ppRow,
  3102.                                   cbBarInfo**    ppBar
  3103.                                 )
  3104. {
  3105.     (*ppRow) = NULL;
  3106.     (*ppBar) = NULL;
  3107.  
  3108.     size_t i;
  3109.     for ( i = 0; i != mRows.Count(); ++i )
  3110.     {
  3111.         cbRowInfo& row = *mRows[i];
  3112.  
  3113.         *ppRow = &row;
  3114.  
  3115.         // hit-test handles of the row, if present
  3116.  
  3117.         if ( row.mHasUpperHandle )
  3118.         {
  3119.             if ( HasPoint( pos, 0, row.mRowY,
  3120.                            row.mRowWidth, mProps.mResizeHandleSize ) )
  3121.  
  3122.                 return CB_UPPER_ROW_HANDLE_HITTED;
  3123.         }
  3124.         else
  3125.         if ( row.mHasLowerHandle )
  3126.         {
  3127.             if ( HasPoint( pos, 0, row.mRowY + row.mRowHeight - mProps.mResizeHandleSize, 
  3128.                            row.mRowWidth, mProps.mResizeHandleSize ) )
  3129.  
  3130.                     return CB_LOWER_ROW_HANDLE_HITTED;
  3131.         }
  3132.  
  3133.         // hit-test bar handles and bar content
  3134.  
  3135.         size_t k;
  3136.         for ( k = 0; k != row.mBars.Count(); ++k )
  3137.         {
  3138.             cbBarInfo& bar    = *row.mBars[k];
  3139.             wxRect&    bounds = bar.mBounds;
  3140.  
  3141.             *ppBar = &bar;
  3142.  
  3143.             if ( bar.mHasLeftHandle )
  3144.             {
  3145.                 if ( HasPoint( pos, bounds.x, bounds.y,
  3146.                                mProps.mResizeHandleSize, bounds.height ) )
  3147.  
  3148.                     return CB_LEFT_BAR_HANDLE_HITTED;
  3149.             }
  3150.             else
  3151.             if ( bar.mHasRightHandle )
  3152.             {
  3153.                 if ( HasPoint( pos, bounds.x + bounds.width - mProps.mResizeHandleSize, bounds.y,
  3154.                                mProps.mResizeHandleSize, bounds.height ) )
  3155.                 
  3156.                     return CB_RIGHT_BAR_HANDLE_HITTED;
  3157.             }
  3158.  
  3159.             if ( HasPoint( pos, bounds.x, bounds.y, bounds.width, bounds.height ) )
  3160.                 return CB_BAR_CONTENT_HITTED;
  3161.  
  3162.         } // hit-test next bar
  3163.  
  3164.     } // next row
  3165.  
  3166.     return CB_NO_ITEMS_HITTED;
  3167. }
  3168.  
  3169. void cbDockPane::GetBarResizeRange( cbBarInfo* pBar, int* from, int *till,
  3170.                                     bool forLeftHandle )
  3171. {
  3172.     cbBarInfo* pGivenBar = pBar;
  3173.  
  3174.     int notFree = 0;
  3175.  
  3176.     // calc unavailable space from the left
  3177.  
  3178.     while( pBar->mpPrev )
  3179.     {
  3180.         pBar = pBar->mpPrev;
  3181.  
  3182.         if ( !pBar->IsFixed() ) notFree += mProps.mMinCBarDim.x;
  3183.                                 else notFree += pBar->mBounds.width;
  3184.     }
  3185.  
  3186.     *from = notFree;
  3187.  
  3188.     pBar = pGivenBar;
  3189.  
  3190.     notFree = 0;
  3191.  
  3192.     // calc unavailable space from the right
  3193.  
  3194.     while( pBar->mpNext )
  3195.     {
  3196.         pBar = pBar->mpNext;
  3197.  
  3198.         if ( pBar->mBounds.x >= mPaneWidth ) break;
  3199.  
  3200.         // treat not-fixed bars as minimized
  3201.  
  3202.         if ( !pBar->IsFixed() ) 
  3203.             
  3204.             notFree += mProps.mMinCBarDim.x;
  3205.         else 
  3206.         {
  3207.             if ( pBar->mBounds.x + pBar->mBounds.width >= mPaneWidth )
  3208.             {
  3209.                 notFree += mPaneWidth - pBar->mBounds.x;
  3210.                 break;
  3211.             }
  3212.             else
  3213.                 notFree += pBar->mBounds.width;
  3214.         }
  3215.  
  3216.     } 
  3217.  
  3218.     *till = mPaneWidth - notFree;
  3219.  
  3220.     // do not let resizing totally deform the bar itself
  3221.  
  3222.     if ( forLeftHandle )
  3223.     
  3224.         (*till) -= mProps.mMinCBarDim.x;
  3225.     else
  3226.     
  3227.         (*from) += mProps.mMinCBarDim.x;
  3228. }
  3229.  
  3230. int cbDockPane::GetMinimalRowHeight( cbRowInfo* pRow )
  3231. {
  3232.     int height = mProps.mMinCBarDim.y;
  3233.  
  3234.     size_t i;
  3235.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  3236.     {
  3237.         if ( pRow->mBars[i]->IsFixed() )
  3238.             height = wxMax( height, pRow->mBars[i]->mBounds.height );
  3239.     }
  3240.  
  3241.     if ( pRow->mHasUpperHandle )
  3242.         height += mProps.mResizeHandleSize;
  3243.  
  3244.     if ( pRow->mHasLowerHandle )
  3245.         height += mProps.mResizeHandleSize;
  3246.     
  3247.     return height;
  3248. }
  3249.  
  3250. void cbDockPane::SetRowHeight( cbRowInfo* pRow, int newHeight )
  3251. {
  3252.     if ( pRow->mHasUpperHandle )
  3253.  
  3254.         newHeight -= mProps.mResizeHandleSize;
  3255.  
  3256.     if ( pRow->mHasLowerHandle )
  3257.  
  3258.         newHeight -= mProps.mResizeHandleSize;
  3259.  
  3260.     size_t i;
  3261.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  3262.     {
  3263.         if ( !pRow->mBars[i]->IsFixed() )
  3264.             pRow->mBars[i]->mBounds.height = newHeight;
  3265.     }
  3266. }
  3267.  
  3268. void cbDockPane::GetRowResizeRange( cbRowInfo* pRow, int* from, int* till,
  3269.                                     bool forUpperHandle )
  3270. {
  3271.     cbRowInfo* pGivenRow = pRow;
  3272.  
  3273.     // calc unavailable space from above
  3274.  
  3275.     int notFree = 0;
  3276.  
  3277.     while( pRow->mpPrev )
  3278.     {
  3279.         pRow = pRow->mpPrev;
  3280.  
  3281.         notFree += GetMinimalRowHeight( pRow );
  3282.  
  3283.     };
  3284.  
  3285.     *from = notFree;    
  3286.  
  3287.     // allow accupy the client window space by resizing pane rows
  3288.     if ( mAlignment == FL_ALIGN_BOTTOM )
  3289.  
  3290.         *from -= mpLayout->GetClientHeight();
  3291.     else
  3292.     if ( mAlignment == FL_ALIGN_RIGHT )
  3293.  
  3294.         *from -= mpLayout->GetClientWidth();
  3295.  
  3296.     // calc unavailable space from below
  3297.  
  3298.     pRow = pGivenRow;
  3299.  
  3300.     notFree = 0;
  3301.  
  3302.     while( pRow->mpNext )
  3303.     {
  3304.         pRow = pRow->mpNext;
  3305.  
  3306.         notFree += GetMinimalRowHeight( pRow );
  3307.  
  3308.     }
  3309.  
  3310.     *till = mPaneHeight - notFree;  
  3311.  
  3312.     // allow adjustinig pane space vs. client window space by resizing pane row heights
  3313.  
  3314.     if ( mAlignment == FL_ALIGN_TOP )
  3315.  
  3316.         *till += mpLayout->GetClientHeight();
  3317.     else
  3318.     if ( mAlignment == FL_ALIGN_LEFT )
  3319.  
  3320.         *till += mpLayout->GetClientWidth();
  3321.  
  3322.     // do not let the resizing of the row totally squeeze the row itself
  3323.  
  3324.     cbRowInfo& row = *pGivenRow;
  3325.  
  3326.     if ( forUpperHandle )
  3327.     {   
  3328.         *till = row.mRowY + row.mRowHeight - GetMinimalRowHeight( pGivenRow );
  3329.  
  3330.         if ( row.mHasUpperHandle )
  3331.  
  3332.             *till -= mProps.mResizeHandleSize;
  3333.     }
  3334.     else
  3335.     {
  3336.         *from += GetMinimalRowHeight( pGivenRow );
  3337.  
  3338.         if ( row.mHasLowerHandle )
  3339.  
  3340.             *from -= mProps.mResizeHandleSize;
  3341.     }
  3342. }
  3343.  
  3344. void cbDockPane::ResizeRow( cbRowInfo* pRow, int ofs, 
  3345.                             bool forUpperHandle )
  3346. {
  3347.     cbResizeRowEvent evt( pRow, ofs, forUpperHandle, this );
  3348.  
  3349.     mpLayout->FirePluginEvent( evt );
  3350. }
  3351.  
  3352. void cbDockPane::ResizeBar( cbBarInfo* pBar, int ofs, 
  3353.                             bool forLeftHandle )
  3354. {
  3355.     pBar->mpRow->mpExpandedBar = NULL;
  3356.  
  3357.     mpLayout->GetUpdatesManager().OnStartChanges();
  3358.  
  3359.     wxRect&  bounds = pBar->mBounds;
  3360.  
  3361.     if ( forLeftHandle )
  3362.     {
  3363.         // do not allow bar width become less then minimal
  3364.         if ( bounds.x + ofs > bounds.x + bounds.width - mProps.mMinCBarDim.x )
  3365.         {
  3366.             bounds.width = mProps.mMinCBarDim.x;
  3367.             bounds.x += ofs;
  3368.         }
  3369.         else
  3370.         {
  3371.             bounds.x     += ofs;
  3372.             bounds.width -= ofs;
  3373.         }
  3374.     }
  3375.     else
  3376.     {
  3377.         // move bar left if necessary       
  3378.         if ( bounds.width + ofs < mProps.mMinCBarDim.x )
  3379.         {
  3380.             bounds.x     = bounds.x + bounds.width + ofs - mProps.mMinCBarDim.x;
  3381.             bounds.width = mProps.mMinCBarDim.x;
  3382.         }
  3383.         else
  3384.             // resize right border only
  3385.             bounds.width += ofs;
  3386.     }
  3387.  
  3388.  
  3389.     cbRowInfo* pToRow = pBar->mpRow;
  3390.  
  3391.     this->RemoveBar( pBar );
  3392.  
  3393.     InsertBar( pBar, pToRow );
  3394.  
  3395.     mpLayout->RecalcLayout(FALSE);
  3396.  
  3397.     mpLayout->GetUpdatesManager().OnFinishChanges();
  3398.     mpLayout->GetUpdatesManager().UpdateNow();
  3399. }
  3400.  
  3401.  
  3402. /*** row/bar resizing related methods ***/
  3403.  
  3404. void cbDockPane::DrawVertHandle( wxDC& dc, int x, int y, int height )
  3405. {
  3406.     int lower = y + height;
  3407.  
  3408.     dc.SetPen( mpLayout->mLightPen );
  3409.     dc.DrawLine( x,y, x, lower );
  3410.  
  3411.     dc.SetPen( mpLayout->mGrayPen );
  3412.     int i;
  3413.     for ( i = 0; i != mProps.mResizeHandleSize-1; ++i )
  3414.     {
  3415.         ++x;
  3416.         dc.DrawLine( x,y, x, lower );
  3417.     }
  3418.  
  3419.     dc.SetPen( mpLayout->mDarkPen );
  3420.     ++x;
  3421.     dc.DrawLine( x,y, x, lower );
  3422.  
  3423.     dc.SetPen( mpLayout->mBlackPen );
  3424.     ++x;
  3425.     dc.DrawLine( x,y, x, lower );
  3426. }
  3427.  
  3428. void cbDockPane::DrawHorizHandle( wxDC& dc, int x, int y, int width  )
  3429. {
  3430.     int right = x + width;
  3431.  
  3432.     dc.SetPen( mpLayout->mLightPen );
  3433.     dc.DrawLine( x,y, right, y );
  3434.  
  3435.     dc.SetPen( mpLayout->mGrayPen );
  3436.  
  3437.     int i;
  3438.     for ( i = 0; i != mProps.mResizeHandleSize-1; ++i )
  3439.     {
  3440.         ++y;
  3441.         dc.DrawLine( x,y, right, y );
  3442.     }
  3443.  
  3444.     dc.SetPen( mpLayout->mDarkPen );
  3445.     dc.DrawLine( x,y, right, ++y );
  3446.  
  3447.     dc.SetPen( mpLayout->mBlackPen );
  3448.     dc.DrawLine( x,y, right, ++y );
  3449. }
  3450.  
  3451. cbBarInfo* cbDockPane::GetBarInfoByWindow( wxWindow* pBarWnd )
  3452. {
  3453.     wxBarIterator i( mRows );
  3454.  
  3455.     while( i.Next() )
  3456.     
  3457.         if ( i.BarInfo().mpBarWnd == pBarWnd )
  3458.  
  3459.             return &i.BarInfo();
  3460.  
  3461.     return NULL;
  3462. }
  3463.  
  3464. void cbDockPane::GetRowShapeData( cbRowInfo* pRow, wxList* pLst )
  3465. {
  3466.     pLst->DeleteContents( TRUE );
  3467.     pLst->Clear();
  3468.  
  3469.     size_t i;
  3470.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  3471.     {
  3472.         cbBarInfo& bar = *pRow->mBars[i];
  3473.  
  3474.         cbBarShapeData* pData = new cbBarShapeData();
  3475.  
  3476.         pLst->Append( (wxObject*)pData );
  3477.  
  3478.         pData->mBounds   = bar.mBounds;
  3479.         pData->mLenRatio = bar.mLenRatio;
  3480.     }
  3481. }
  3482.  
  3483. void cbDockPane::SetRowShapeData( cbRowInfo* pRow, wxList* pLst )
  3484. {
  3485.     if ( pLst->First() == NULL )
  3486.         return;
  3487.  
  3488.     wxNode* pData = pLst->First();
  3489.  
  3490.     size_t i;
  3491.     for ( i = 0; i != pRow->mBars.Count(); ++i )
  3492.     {
  3493.         wxASSERT( pData ); // DBG::
  3494.  
  3495.         cbBarInfo& bar = *pRow->mBars[i];;
  3496.  
  3497.         cbBarShapeData& data = *((cbBarShapeData*)pData->Data());
  3498.  
  3499.         bar.mBounds   = data.mBounds;
  3500.         bar.mLenRatio = data.mLenRatio;
  3501.  
  3502.         pData = pData->Next();
  3503.     }
  3504. }
  3505.  
  3506. /***** Implementation for class cbUpdatesManagerBase *****/
  3507.  
  3508. IMPLEMENT_ABSTRACT_CLASS( cbUpdatesManagerBase, wxObject )
  3509.  
  3510. /***** Implementation for class cbPluginBase *****/
  3511.  
  3512. IMPLEMENT_ABSTRACT_CLASS( cbPluginBase, wxEvtHandler )
  3513.  
  3514. cbPluginBase::~cbPluginBase()
  3515. {
  3516.     // nothing
  3517. }
  3518.  
  3519. bool cbPluginBase::ProcessEvent(wxEvent& event)
  3520. {
  3521.     if ( mPaneMask == wxALL_PANES ) 
  3522.  
  3523.         return wxEvtHandler::ProcessEvent( event );
  3524.  
  3525.     // extract mask info. from received event
  3526.  
  3527.     cbPluginEvent& evt = *( (cbPluginEvent*)&event );
  3528.  
  3529.     if ( evt.mpPane == 0 &&
  3530.          mPaneMask  == wxALL_PANES )
  3531.  
  3532.          return wxEvtHandler::ProcessEvent( event );
  3533.  
  3534.     int mask = 0;
  3535.  
  3536.     switch ( evt.mpPane->mAlignment )
  3537.     {
  3538.         case FL_ALIGN_TOP    : mask = FL_ALIGN_TOP_PANE;   break;
  3539.         case FL_ALIGN_BOTTOM : mask = FL_ALIGN_BOTTOM_PANE;break;
  3540.         case FL_ALIGN_LEFT   : mask = FL_ALIGN_LEFT_PANE;  break;
  3541.         case FL_ALIGN_RIGHT  : mask = FL_ALIGN_RIGHT_PANE; break;
  3542.     }
  3543.  
  3544.     // if event's pane maks matches the plugin's mask
  3545.  
  3546.     if ( mPaneMask & mask ) 
  3547.  
  3548.         return wxEvtHandler::ProcessEvent( event );
  3549.  
  3550.     // otherwise pass to the next handler if present
  3551.  
  3552.     if ( GetNextHandler() && GetNextHandler()->ProcessEvent( event ) )
  3553.  
  3554.         return TRUE;
  3555.     else
  3556.         return FALSE;
  3557. }
  3558.  
  3559.