1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     cbBarDragPlugin implementation 
   4 // Author:      Aleksandras Gluchovas 
   8 // Copyright:   (c) Aleksandras Gluchovas 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13     #pragma implementation "bardragpl.h" 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  27 #include "wx/fl/bardragpl.h" 
  29 #define POS_UNDEFINED -32768 
  31 // helpers, FOR NOW:: static 
  33 static inline bool rect_hits_rect( const wxRect
& r1
, const wxRect
& r2 
) 
  35         if ( ( r2
.x 
>= r1
.x 
&& r2
.x 
<= r1
.x 
+ r1
.width 
) || 
  36                  ( r1
.x 
>= r2
.x 
&& r1
.x 
<= r2
.x 
+ r2
.width 
) ) 
  38                 if ( ( r2
.y 
>= r1
.y 
&& r2
.y 
<= r1
.y 
+ r1
.height 
) || 
  39                          ( r1
.y 
>= r2
.y 
&& r1
.y 
<= r2
.y 
+ r2
.height 
) ) 
  46 static inline bool rect_contains_point( const wxRect
& rect
, int x
, int y 
) 
  48         return ( x 
>= rect
.x 
&& 
  50                          x 
<  rect
.x 
+ rect
.width  
&& 
  51                          y 
<  rect
.y 
+ rect
.height 
); 
  54 /***** Implementation for class cbBarDragPlugin *****/ 
  56 IMPLEMENT_DYNAMIC_CLASS( cbBarDragPlugin
, cbPluginBase 
) 
  58 BEGIN_EVENT_TABLE( cbBarDragPlugin
, cbPluginBase 
) 
  60         //EVT_PL_LEFT_DOWN          ( cbBarDragPlugin::OnLButtonDown      ) 
  61         EVT_PL_LEFT_UP                    ( cbBarDragPlugin::OnLButtonUp        
) 
  62         EVT_PL_MOTION                     ( cbBarDragPlugin::OnMouseMove        
) 
  63         EVT_PL_DRAW_HINT_RECT     ( cbBarDragPlugin::OnDrawHintRect     
) 
  64         EVT_PL_START_BAR_DRAGGING ( cbBarDragPlugin::OnStartBarDragging 
) 
  65         EVT_PL_LEFT_DCLICK                ( cbBarDragPlugin::OnLDblClick                
) 
  69 cbBarDragPlugin::cbBarDragPlugin(void) 
  71         : mBarDragStarted    ( FALSE 
), 
  75           mpDraggedBar       ( NULL 
), 
  76           mInClientHintBorder( 4 ) 
  79 cbBarDragPlugin::cbBarDragPlugin( wxFrameLayout
* pPanel
, int paneMask 
) 
  81         : cbPluginBase( pPanel
, paneMask 
), 
  83           mBarDragStarted    ( FALSE 
), 
  87           mpDraggedBar       ( NULL 
), 
  88           mInClientHintBorder( 4 ) 
  91 cbBarDragPlugin::~cbBarDragPlugin() 
  96 // helper methods (protected) 
  98 // clips (top/bottom) or (right/left) edges against the frame's bounding rect. 
 100 void do_clip_edges( int len
, int& rectPos
, int& rectLen 
) 
 110         if ( rectPos 
> len
-1 ) 
 116         if ( rectPos 
+ rectLen 
- 1 > len 
) 
 118                 rectLen 
-= (rectPos 
+ rectLen
) - len 
+ 1; 
 121 void cbBarDragPlugin::ClipRectInFrame( wxRect
& rect 
) 
 124         mpLayout
->GetParentFrame().GetClientSize( &w
, &h 
); 
 126         do_clip_edges( w
, rect
.x
, rect
.width  
); 
 127         do_clip_edges( h
, rect
.y
, rect
.height 
); 
 130 void cbBarDragPlugin::ClipPosInFrame( wxPoint
& pos 
) 
 133         mpLayout
->GetParentFrame().GetClientSize( &w
, &h 
); 
 145 void cbBarDragPlugin::AdjustHintRect( wxPoint
& mousePos 
) 
 147         mHintRect
.x 
= mousePos
.x 
- mMouseInRectX
; 
 148         mHintRect
.y 
= mousePos
.y 
- mMouseInRectY
; 
 151 cbDockPane
* cbBarDragPlugin::HitTestPanes( wxRect
& rect 
) 
 153         //wxRect clipped = rect; 
 155         //ClipRectInFrame( clipped ); 
 157         cbDockPane
** pPanes 
= mpLayout
->GetPanesArray(); 
 159         for( int i 
= 0; i 
!= MAX_PANES
; ++i 
) 
 161                 if ( rect_hits_rect( pPanes
[i
]->mBoundsInParent
, rect 
) ) 
 168 cbDockPane
* cbBarDragPlugin::HitTestPanes( wxPoint
& pos 
) 
 170         wxPoint clipped 
= pos
; 
 172         //ClipPosInFrame( pos ); 
 174         cbDockPane
** pPanes 
= mpLayout
->GetPanesArray(); 
 176         for( int i 
= 0; i 
!= MAX_PANES
; ++i 
) 
 178                 if ( rect_contains_point( pPanes
[i
]->mBoundsInParent
, clipped
.x
, clipped
.y 
) ) 
 185 bool cbBarDragPlugin::HitsPane( cbDockPane
* pPane
, wxRect
& rect 
) 
 187         return rect_hits_rect( pPane
->mBoundsInParent
, rect 
); 
 190 int cbBarDragPlugin::GetDistanceToPane( cbDockPane
* pPane
, wxPoint
& mousePos 
) 
 192         wxRect
& bounds 
= pPane
->mBoundsInParent
; 
 194         switch( pPane
->mAlignment 
) 
 196                 case FL_ALIGN_TOP    
: return mousePos
.y 
- ( bounds
.y 
+ bounds
.height 
); 
 198                 case FL_ALIGN_BOTTOM 
: return bounds
.y 
- mousePos
.y
; 
 200                 case FL_ALIGN_LEFT   
: return mousePos
.x 
- ( bounds
.x 
+ bounds
.width  
); 
 202                 case FL_ALIGN_RIGHT  
: return bounds
.x 
- mousePos
.x
; 
 204                 default : return 0; // never reached 
 210 bool cbBarDragPlugin::IsInOtherPane( wxPoint
& mousePos 
) 
 212         cbDockPane
* pPane 
= HitTestPanes( mousePos 
); 
 214         if ( pPane 
&& pPane 
!= mpCurPane 
) return TRUE
; 
 218 bool cbBarDragPlugin::IsInClientArea( wxPoint
& mousePos 
) 
 220         return  ( HitTestPanes( mousePos 
) == NULL 
); 
 223 bool cbBarDragPlugin::IsInClientArea( wxRect
& rect 
) 
 225         return ( HitTestPanes( rect 
) == NULL 
); 
 228 void cbBarDragPlugin::CalcOnScreenDims( wxRect
& rect 
) 
 230         if ( !mpCurPane 
|| mpDraggedBar
->IsFixed() ) return; 
 232         wxRect inPane 
= rect
; 
 234         mpCurPane
->FrameToPane( &inPane 
); 
 236         int rowNo 
= mpCurPane
->GetRowAt( inPane
.y
, inPane
.y 
+ inPane
.height 
); 
 238         bool isMaximized 
= ( rowNo 
>= (int)mpCurPane
->GetRowList().Count() || rowNo 
< 0 ); 
 243                 inPane
.width 
= mpCurPane
->mPaneWidth
; 
 245                 mpCurPane
->PaneToFrame( &inPane 
); 
 253 static inline void check_upper_overrun( int& pos
, int width
, int mousePos 
) 
 255         if ( mousePos 
>= pos 
+ width 
) 
 257                 pos 
= mousePos 
- width
/2; 
 260 static inline void check_lower_overrun( int& pos
, int width
, int mousePos 
) 
 262         if ( mousePos 
<= pos 
) 
 264                 pos 
= mousePos 
- width
/2; 
 267 void cbBarDragPlugin::StickToPane( cbDockPane
* pPane
, wxPoint
& mousePos 
) 
 269         int wInPane 
= GetBarWidthInPane ( pPane 
); 
 270         int hInPane 
= GetBarHeightInPane( pPane 
); 
 272         // adjsut hint-rect horizontally (in pane's orientation) 
 274         if ( pPane
->IsHorizontal() ) 
 276                 mHintRect
.width  
= wInPane
; 
 277                 mHintRect
.height 
= hInPane
; 
 281                 mHintRect
.height 
= wInPane
; 
 282                 mHintRect
.width  
= hInPane
; 
 285         // adjsut hint-rect vertically (in pane's orientation) 
 287         wxRect
& bounds 
= pPane
->mBoundsInParent
; 
 289         // TRUE, if hint enters the pane through it's lower edge 
 291         bool fromLowerEdge 
= ( pPane
->IsHorizontal() )  
 292                                                  ? mousePos
.y 
> bounds
.y
 
 293                                                  : mousePos
.x 
> bounds
.x
; 
 295         // NOTE:: about all the below min/max things: they are meant to ensure 
 296         //        that the mouse pointer doesn't overrun (leave) the hint-rectangle 
 297         //        when its dimensions are recalculated upon sticking it to the pane 
 299         if ( pPane
->IsHorizontal() && fromLowerEdge 
) 
 301                 int paneBottomEdgeY 
= bounds
.y 
+ bounds
.height
; 
 303                 mHintRect
.y 
= wxMin( paneBottomEdgeY
, mousePos
.y 
); 
 305                 check_lower_overrun( mHintRect
.y
, hInPane
, mousePos
.y 
); 
 309         if ( pPane
->IsHorizontal() && !fromLowerEdge 
) 
 311                 int paneTopEdgeY 
= bounds
.y
; 
 313                 mHintRect
.y 
= wxMax( paneTopEdgeY 
- hInPane
, mousePos
.y 
- hInPane 
); 
 315                 check_upper_overrun( mHintRect
.y
, hInPane
, mousePos
.y 
); 
 318         if ( !pPane
->IsHorizontal() && fromLowerEdge 
) 
 320                 int paneRightEdgeX 
= bounds
.x 
+ bounds
.width
; 
 322                 mHintRect
.x 
= wxMin( paneRightEdgeX
, mousePos
.x 
); 
 324                 check_lower_overrun( mHintRect
.x
, hInPane
, mousePos
.x 
); 
 327         if ( !pPane
->IsHorizontal() && !fromLowerEdge 
) 
 329                 int paneLeftEdgeX 
= bounds
.x
; 
 331                 mHintRect
.x 
= wxMax( paneLeftEdgeX 
- hInPane
, mousePos
.x 
- hInPane 
); 
 333                 check_upper_overrun( mHintRect
.x
, hInPane
, mousePos
.x 
); 
 336         mMouseInRectX 
= mousePos
.x 
- mHintRect
.x
; 
 337         mMouseInRectY 
= mousePos
.y 
- mHintRect
.y
; 
 339         mpCurPane 
= pPane
; // memorize pane to which the hint is currently sticked 
 342 void cbBarDragPlugin::UnstickFromPane( cbDockPane
* pPane
, wxPoint
& mousePos 
) 
 344         // unsticking causes rectangle to get the shape in which 
 345         // dragged control-bar would be when floated 
 347         int newWidth  
= mpDraggedBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].x
; 
 348         int newHeight 
= mpDraggedBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].y
; 
 350         wxRect
& flBounds 
= mpDraggedBar
->mDimInfo
.mBounds
[wxCBAR_FLOATING
]; 
 352         if ( flBounds
.width 
!= -1 ) 
 354                 newWidth  
= flBounds
.width
; 
 355                 newHeight 
= flBounds
.height
; 
 358         mHintRect
.width  
= newWidth
; 
 359         mHintRect
.height 
= newHeight
; 
 361         wxRect
& bounds 
= pPane
->mBoundsInParent
; 
 363         // TRUE, if hint leaves the pane through it's lower edge 
 365         bool fromLowerEdge 
= ( pPane
->IsHorizontal() )  
 366                                                  ? mousePos
.y 
> bounds
.y
 
 367                                                  : mousePos
.x 
> bounds
.x
; 
 369         // NOTE:: ...all the below min/max things - see comments about it in StickToPane(..) 
 371         if ( pPane
->IsHorizontal() && fromLowerEdge 
) 
 373 //              bool fromLowerEdge = mousePos.y > bounds.y; 
 375                 mHintRect
.y 
= wxMax( bounds
.y 
+ bounds
.height 
+ 1, mousePos
.y 
- newHeight 
); 
 377                 check_upper_overrun( mHintRect
.y
, newHeight
, mousePos
.y 
); 
 379                 // this is how MFC's hint behaves: 
 381                 if ( mMouseInRectX 
> newWidth 
) 
 383                         mHintRect
.x 
= mousePos
.x 
- ( newWidth 
/ 2 ); 
 386         if ( pPane
->IsHorizontal() && !fromLowerEdge 
) 
 388                 mHintRect
.y 
= wxMin( bounds
.y 
- newHeight 
- 1, mousePos
.y 
); 
 392                 if ( mMouseInRectX 
> newWidth 
) 
 394                         mHintRect
.x 
= mousePos
.x 
- ( newWidth 
/ 2 ); 
 396                 check_lower_overrun( mHintRect
.y
, newHeight
, mousePos
.y 
); 
 399         if ( !pPane
->IsHorizontal() && fromLowerEdge 
) 
 401                 mHintRect
.x 
= wxMax( bounds
.x 
+ bounds
.width
, mousePos
.x 
- newWidth 
); 
 405                 if ( mMouseInRectY 
> newHeight 
) 
 407                         mHintRect
.y 
= mousePos
.y 
- ( newHeight 
/ 2 ); 
 409                 check_upper_overrun( mHintRect
.x
, newWidth
, mousePos
.x 
); 
 412         if ( !pPane
->IsHorizontal() && !fromLowerEdge 
) 
 414                 mHintRect
.x 
= wxMin( bounds
.x 
- newWidth 
- 1, mousePos
.x 
); 
 418                 if ( mMouseInRectY 
> newHeight 
) 
 420                         mHintRect
.y 
= mousePos
.y 
- ( newHeight 
/ 2 ); 
 422                 check_lower_overrun( mHintRect
.x
, newWidth
, mousePos
.x 
); 
 425         mMouseInRectX 
= mousePos
.x 
- mHintRect
.x
; 
 426         mMouseInRectY 
= mousePos
.y 
- mHintRect
.y
; 
 431 int cbBarDragPlugin::GetBarWidthInPane( cbDockPane
* pPane 
) 
 433         if ( pPane 
== mpSrcPane 
) 
 435                 return mBarWidthInSrcPane
; 
 437         // this is how MFC's bars behave: 
 439         if ( pPane
->IsHorizontal() ) 
 441                 return mpDraggedBar
->mDimInfo
.mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].x
; 
 443                 return mpDraggedBar
->mDimInfo
.mSizes
[wxCBAR_DOCKED_VERTICALLY  
].x
; 
 446 int cbBarDragPlugin::GetBarHeightInPane( cbDockPane
* pPane 
) 
 448         if ( pPane
->IsHorizontal() ) 
 450                 return mpDraggedBar
->mDimInfo
.mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].y
; 
 452                 return mpDraggedBar
->mDimInfo
.mSizes
[wxCBAR_DOCKED_VERTICALLY  
].y
; 
 455 void cbBarDragPlugin::ShowHint( bool prevWasInClient 
) 
 457         bool wasDocked 
= FALSE
; 
 460         if ( mpSrcPane
->mProps
.mRealTimeUpdatesOn 
== FALSE 
) 
 462                 // do heavy calculations first 
 464                 wxRect actualRect 
= mHintRect
; // will be adjusted depending on drag-settings 
 466                 if ( mpSrcPane
->mProps
.mExactDockPredictionOn 
&& mpCurPane 
) 
 471                      mpLayout
->RedockBar( mpDraggedBar
, mHintRect
, mpCurPane
, FALSE 
); 
 473                         wxASSERT( success 
); // DBG:: 
 475                         actualRect 
= mpDraggedBar
->mBounds
; 
 477                         mpCurPane
->PaneToFrame( &actualRect 
); 
 480                         CalcOnScreenDims( actualRect 
); 
 482                 // release previous hint 
 484                 if ( mPrevHintRect
.x 
!= POS_UNDEFINED 
) 
 486                         // erase previous rectangle 
 488                         cbDrawHintRectEvent 
evt( mPrevHintRect
, prevWasInClient
, TRUE
, FALSE 
); 
 490                         mpLayout
->FirePluginEvent( evt 
); 
 495                 cbDrawHintRectEvent 
evt( actualRect
, mpCurPane 
== NULL
, FALSE
, FALSE 
); 
 497                 mpLayout
->FirePluginEvent( evt 
); 
 499                 mPrevHintRect 
= actualRect
; 
 503                 // otherwise, if real-time updates option is ON 
 505             if ( mpDraggedBar
->mState 
!= wxCBAR_FLOATING 
&& !mpCurPane 
) 
 507                     mpLayout
->SetBarState( mpDraggedBar
, wxCBAR_FLOATING
, TRUE 
); 
 510             if ( mpDraggedBar
->mState 
== wxCBAR_FLOATING 
&& mpCurPane 
) 
 512                     mpLayout
->SetBarState( mpDraggedBar
, wxCBAR_DOCKED_HORIZONTALLY
, FALSE 
); 
 519                         mpLayout
->GetUpdatesManager().OnStartChanges(); 
 523                                 mpDraggedBar
->mUMgrData
.SetDirty( TRUE 
); 
 528                      mpLayout
->RedockBar( mpDraggedBar
, mHintRect
, mpCurPane
, FALSE 
); 
 530                         wxASSERT( success 
); // DBG :: 
 532                         mpLayout
->GetUpdatesManager().OnFinishChanges(); 
 533                         mpLayout
->GetUpdatesManager().UpdateNow(); 
 537                         if ( mpLayout
->mFloatingOn 
) 
 539                                 // move the top-most floated bar around as user drags the hint 
 541                                 mpDraggedBar
->mDimInfo
.mBounds
[ wxCBAR_FLOATING 
] = mHintRect
; 
 543                                 mpLayout
->ApplyBarProperties( mpDraggedBar 
); 
 549 /*** event handlers ***/ 
 551 void cbBarDragPlugin::OnMouseMove( cbMotionEvent
& event 
) 
 553         // calculate postion in frame's coordiantes 
 555         if ( !mBarDragStarted 
) 
 557                 event
.Skip(); // pass event to the next plugin 
 561         wxPoint mousePos 
= event
.mPos
; 
 563         event
.mpPane
->PaneToFrame( &mousePos
.x
, &mousePos
.y 
); 
 565         bool   prevIsInClient 
= ( mpCurPane 
== 0 ); 
 567         AdjustHintRect( mousePos 
); 
 569         // if the hint-rect is not "tempted" to any pane yet 
 571         if ( mpCurPane 
== NULL 
) 
 573                 cbDockPane
* pPane 
= HitTestPanes( mHintRect 
); 
 577                         // enable sticking again, if we've left the pane completely 
 580                 if ( mCanStick 
&& pPane 
&&  
 581                          GetDistanceToPane( pPane
, mousePos 
) < GetBarHeightInPane( pPane 
) ) 
 583                         StickToPane( pPane
, mousePos 
); 
 585                         if ( pPane 
&& HitTestPanes( mousePos 
) == pPane 
&& 0 ) // FOR NOW:: disabled 
 587                                 StickToPane( pPane
, mousePos 
); 
 591                 // otherwise, when rect is now sticked to some of the panes 
 592                 // check if it should still remain in this pane 
 596                 bool mouseInOther 
= IsInOtherPane( mousePos 
); 
 600                                 cbDockPane
* pPane 
= HitTestPanes( mousePos 
); 
 602                                 StickToPane( pPane
, mousePos 
); 
 606                         if ( IsInClientArea( mousePos 
) ) 
 608                                 cbDockPane
* pPane 
= HitTestPanes( mHintRect 
); 
 611                                          pPane 
!= mpCurPane 
&& 
 612                                          GetDistanceToPane( pPane
, mousePos 
) < GetBarHeightInPane( pPane 
) ) 
 614                                                 StickToPane( pPane
, mousePos 
); 
 618                                         UnstickFromPane( mpCurPane
, mousePos 
); 
 620                                         // FOR NOW:: disabled, would cause some mess 
 621                                         //mCanStick = FALSE; // prevents from sticking to this 
 622                                                                          // pane again, flag is reset when hint-rect 
 623                                                                          // leaves the pane completely 
 626                                 if ( GetDistanceToPane( pPane
, mousePos 
) > GetBarHeightInPane( pPane 
) ) 
 628                                         if ( !HitsPane( mpCurPane
, mHintRect 
) ) 
 630                                                 UnstickFromPane( mpCurPane
, mousePos 
); 
 632                                                 // FOR NOW:: disabled, would cause some mess 
 633                                                 //mCanStick = FALSE; // prevents from sticking to this 
 634                                                                                      // pane again, flag is reset when hint-rect 
 635                                                                                      // leaves the pane completely 
 646         ShowHint( prevIsInClient 
); 
 648         wxCursor
* pPrevCurs 
= mpCurCursor
; 
 652                 mpCurCursor 
= mpLayout
->mpNormalCursor
; 
 656         // if floating is off, and we are in the client 
 657         // area, the cursor will be invalid, otherwise 
 658         // it will be the normal cursor 
 660         if (mpLayout
->mFloatingOn
) 
 662                         mpCurCursor 
= mpLayout
->mpNormalCursor
; 
 666                         mpCurCursor 
= mpLayout
->mpNECursor
; 
 670         if ( pPrevCurs 
!= mpCurCursor 
) 
 671                 mpLayout
->GetParentFrame().SetCursor( *mpCurCursor 
); 
 674 void cbBarDragPlugin::OnLButtonDown( cbLeftDownEvent
& event 
) 
 676         if ( mBarDragStarted  
) 
 678                 wxMessageBox(wxT("DblClick!")); 
 684 void cbBarDragPlugin::OnLButtonUp( cbLeftUpEvent
& event 
) 
 686         if ( mBarDragStarted  
) 
 688                 if ( mpSrcPane
->mProps
.mRealTimeUpdatesOn 
== FALSE 
) 
 690                         // erase current rectangle, and finsih on-screen drawing session 
 692                         cbDrawHintRectEvent 
evt( mPrevHintRect
, mpCurPane 
== NULL
, TRUE
, TRUE 
); 
 694                         mpLayout
->FirePluginEvent( evt 
); 
 696                         if ( mpCurPane 
!= NULL 
) 
 698                                 if ( mpSrcPane
->mProps
.mExactDockPredictionOn 
) 
 700                                         mpLayout
->RedockBar( mpDraggedBar
, mHintRect
, mpCurPane
, FALSE 
); 
 702                                         mpLayout
->GetUpdatesManager().OnFinishChanges(); 
 703                                         mpLayout
->GetUpdatesManager().UpdateNow(); 
 707                     if (mpDraggedBar
->mState 
== wxCBAR_FLOATING
) 
 709                                 mpLayout
->SetBarState( mpDraggedBar
, wxCBAR_DOCKED_HORIZONTALLY
, TRUE
); 
 712                                         mpLayout
->RedockBar( mpDraggedBar
, mHintRect
, mpCurPane 
); 
 717                 if (mpDraggedBar
->mState 
!= wxCBAR_FLOATING
) 
 719                     mpLayout
->SetBarState(mpDraggedBar
, wxCBAR_FLOATING
, true); 
 722                                 mpDraggedBar
->mDimInfo
.mBounds
[ wxCBAR_FLOATING 
] = mHintRect
; 
 723                                 mpLayout
->ApplyBarProperties( mpDraggedBar 
); 
 727                 mHintRect
.width 
= -1; 
 729         // In Windows, at least, the frame needs to have a null cursor 
 730         // else child windows (such as text windows) inherit the cursor 
 732         mpLayout
->GetParentFrame().SetCursor( wxNullCursor 
); 
 734         mpLayout
->GetParentFrame().SetCursor( *mpLayout
->mpNormalCursor 
); 
 737                 mpLayout
->ReleaseEventsFromPane( event
.mpPane 
); 
 738                 mpLayout
->ReleaseEventsFromPlugin( this ); 
 740                 mBarDragStarted 
= FALSE
; 
 742                 if ( mBarWasFloating 
&& mpDraggedBar
->mState 
!= wxCBAR_FLOATING 
) 
 744                         // save bar's floating position before it was docked  
 746                         mpDraggedBar
->mDimInfo
.mBounds
[ wxCBAR_FLOATING 
] = mFloatedBarBounds
; 
 750                 event
.Skip(); // pass event to the next plugin 
 753 void cbBarDragPlugin::OnLDblClick( cbLeftDClickEvent
& event 
) 
 755         int avoidCompilerWarning 
= 1; 
 756         if ( avoidCompilerWarning 
) 
 758                 cbBarInfo
* pHittedBar
; 
 761                 if ( event
.mpPane
->HitTestPaneItems( event
.mPos
,          // in pane's coordiantes 
 763                                                                                          &pHittedBar 
) == CB_BAR_CONTENT_HITTED
 
 766                                 mpLayout
->SetBarState( pHittedBar
, wxCBAR_FLOATING
, TRUE 
); 
 768                                 mpLayout
->RepositionFloatedBar( pHittedBar 
); 
 770                                 return; // event is "eaten" by this plugin 
 773                 mBarDragStarted 
= FALSE
; 
 778         //wxMessageBox("Hi, dblclick arrived!"); 
 781 void cbBarDragPlugin::OnStartBarDragging( cbStartBarDraggingEvent
& event 
) 
 783         mpDraggedBar 
= event
.mpBar
; 
 784         mpSrcPane    
= event
.mpPane
;  
 786         mpLayout
->CaptureEventsForPane( event
.mpPane 
); 
 787         mpLayout
->CaptureEventsForPlugin( this ); 
 789         mpLayout
->GetParentFrame().SetCursor( *mpLayout
->mpNormalCursor 
); 
 791         mBarDragStarted 
= TRUE
; 
 793         wxRect inParent 
= mpDraggedBar
->mBounds
; 
 795         mBarWasFloating 
= mpDraggedBar
->mState 
== wxCBAR_FLOATING
; 
 797         if ( mBarWasFloating 
) 
 799                 inParent 
= mpDraggedBar
->mDimInfo
.mBounds
[ wxCBAR_FLOATING 
]; 
 800                 mFloatedBarBounds 
= inParent
; 
 803                 event
.mpPane
->PaneToFrame( &inParent 
); 
 805         mHintRect
.x 
= POS_UNDEFINED
; 
 807         mHintRect
.width  
= inParent
.width
; 
 808         mHintRect
.height 
= inParent
.height
; 
 810         mMouseInRectX 
= event
.mPos
.x 
- inParent
.x
; 
 811         mMouseInRectY 
= event
.mPos
.y 
- inParent
.y
; 
 813         mpSrcPane 
= event
.mpPane
; 
 815         if ( mpDraggedBar
->mState 
== wxCBAR_FLOATING 
) 
 819                 mpCurPane 
= event
.mpPane
; 
 821         mPrevHintRect
.x 
= POS_UNDEFINED
; 
 823         mCanStick 
= FALSE
; // we're not stuck into any pane now -  
 824                                            // there's nowhere to "stick-twice" 
 826         mBarWidthInSrcPane 
= mpDraggedBar
->mDimInfo
.mSizes
[ mpDraggedBar
->mState 
].x
; 
 828         if ( mpSrcPane
->mProps
.mRealTimeUpdatesOn 
== FALSE 
&&  
 829                  mpSrcPane
->mProps
.mExactDockPredictionOn  
) 
 831                 mpLayout
->GetUpdatesManager().OnStartChanges(); // capture initial state of layout 
 833         // simulate the first mouse movement 
 835         int x 
= event
.mPos
.x
, y 
= event
.mPos
.y
; 
 837         mpSrcPane
->FrameToPane( &x
, &y 
); 
 839         cbMotionEvent 
motionEvt( wxPoint(x
,y
), event
.mpPane 
); 
 842         this->OnMouseMove( motionEvt 
); 
 844         return; // event is "eaten" by this plugin 
 847 /*** on-screen hint-tracking related methods ***/ 
 849 void cbBarDragPlugin::OnDrawHintRect( cbDrawHintRectEvent
& event 
) 
 851         if ( !mpScrDc 
) StartTracking(); 
 853         DoDrawHintRect( event
.mRect
, event
.mIsInClient 
); 
 855         if ( event
.mLastTime 
) 
 860 #define _IMG_A  0xAA    // Note: modified from _A to _IMG_A, _A was already defined (cygwin) 
 861 #define _IMG_B  0x00    // Note: modified from _B to _IMG_A, _B was already defined (cygwin) 
 862 #define _IMG_C  0x55    // Note: modified from _C to _IMG_C, for consistency reasons. 
 863 #define _IMG_D  0x00    // Note: modified from _D to _IMG_D, for consistency reasons. 
 867 static const unsigned char _gCheckerImg
[16] = { _IMG_A
,_IMG_B
,_IMG_C
,_IMG_D
, 
 868                                                                                             _IMG_A
,_IMG_B
,_IMG_C
,_IMG_D
, 
 869                                                                                             _IMG_A
,_IMG_B
,_IMG_C
,_IMG_D
, 
 870                                                                                             _IMG_A
,_IMG_B
,_IMG_C
,_IMG_D
 
 873 void cbBarDragPlugin::StartTracking() 
 875         mpScrDc 
= new wxScreenDC
; 
 877         wxScreenDC::StartDrawingOnTop(&mpLayout
->GetParentFrame()); 
 880 void cbBarDragPlugin::DoDrawHintRect( wxRect
& rect
, bool isInClientRect
) 
 884         RectToScr( rect
, scrRect 
); 
 886         int prevLF 
= mpScrDc
->GetLogicalFunction(); 
 888         mpScrDc
->SetLogicalFunction( wxINVERT 
); 
 890         if ( isInClientRect 
) 
 892                 // BUG BUG BUG (wx):: somehow stippled brush works only   
 893                 //                                        when the bitmap created on stack, not 
 894                 //                                        as a member of the class 
 896                 wxBitmap 
checker( (const char*)_gCheckerImg
, 8,8 ); 
 898                 wxBrush 
checkerBrush( checker 
); 
 900                 mpScrDc
->SetPen( mpLayout
->mNullPen 
); 
 901                 mpScrDc
->SetBrush( checkerBrush 
); 
 903                 int half 
= mInClientHintBorder 
/ 2; 
 905                 mpScrDc
->DrawRectangle( scrRect
.x 
- half
, scrRect
.y 
- half
, 
 906                                             scrRect
.width 
+ 2*half
, mInClientHintBorder 
); 
 908                 mpScrDc
->DrawRectangle( scrRect
.x 
- half
, scrRect
.y 
+ scrRect
.height 
- half
, 
 909                                             scrRect
.width 
+ 2*half
, mInClientHintBorder 
); 
 911                 mpScrDc
->DrawRectangle( scrRect
.x 
- half
, scrRect
.y 
+ half 
- 1, 
 912                                             mInClientHintBorder
, scrRect
.height 
- 2*half 
+ 2); 
 914                 mpScrDc
->DrawRectangle( scrRect
.x 
+ scrRect
.width 
- half
, 
 915                                                                 scrRect
.y 
+ half 
- 1, 
 916                                             mInClientHintBorder
, scrRect
.height 
- 2*half 
+ 2); 
 918                 mpScrDc
->SetBrush( wxNullBrush 
); 
 922                 mpScrDc
->SetPen( mpLayout
->mBlackPen 
); 
 924                 mpScrDc
->DrawLine( scrRect
.x
, scrRect
.y
,  
 925                                                    scrRect
.x 
+ scrRect
.width
, scrRect
.y 
); 
 927                 mpScrDc
->DrawLine( scrRect
.x
, scrRect
.y 
+ 1,  
 928                                                    scrRect
.x
, scrRect
.y 
+ scrRect
.height 
); 
 930                 mpScrDc
->DrawLine( scrRect
.x
+1, scrRect
.y 
+ scrRect
.height
,  
 931                                                    scrRect
.x 
+ scrRect
.width
, scrRect
.y 
+ scrRect
.height 
); 
 933                 mpScrDc
->DrawLine( scrRect
.x 
+ scrRect
.width 
, scrRect
.y
,  
 934                                                    scrRect
.x 
+ scrRect
.width
, scrRect
.y 
+ scrRect
.height 
+ 1); 
 937         mpScrDc
->SetLogicalFunction( prevLF 
); 
 940 void cbBarDragPlugin::DrawHintRect ( wxRect
& rect
, bool isInClientRect
) 
 942         DoDrawHintRect( rect
, isInClientRect 
);  
 945 void cbBarDragPlugin::EraseHintRect( wxRect
& rect
, bool isInClientRect
) 
 947         DoDrawHintRect( rect
, isInClientRect 
);  
 950 void cbBarDragPlugin::FinishTracking() 
 952         wxScreenDC::EndDrawingOnTop(); 
 959 void cbBarDragPlugin::RectToScr( wxRect
& frameRect
, wxRect
& scrRect 
) 
 963         int x 
= frameRect
.x
, y 
= frameRect
.y
; 
 965         mpLayout
->GetParentFrame().ClientToScreen( &x
, &y 
);