1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: cbBarDragPlugin implementation
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleksandras Gluchovas
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
23 #include "wx/fl/bardragpl.h"
25 #define POS_UNDEFINED -32768
27 // helpers, FOR NOW:: static
29 static inline bool rect_hits_rect( const wxRect
& r1
, const wxRect
& r2
)
31 if ( ( r2
.x
>= r1
.x
&& r2
.x
<= r1
.x
+ r1
.width
) ||
32 ( r1
.x
>= r2
.x
&& r1
.x
<= r2
.x
+ r2
.width
) )
33 if ( ( r2
.y
>= r1
.y
&& r2
.y
<= r1
.y
+ r1
.height
) ||
34 ( r1
.y
>= r2
.y
&& r1
.y
<= r2
.y
+ r2
.height
) )
39 static inline bool rect_contains_point( const wxRect
& rect
, int x
, int y
)
41 return ( x
>= rect
.x
&&
43 x
< rect
.x
+ rect
.width
&&
44 y
< rect
.y
+ rect
.height
);
47 /***** Implementation for class cbBarDragPlugin *****/
49 IMPLEMENT_DYNAMIC_CLASS( cbBarDragPlugin
, cbPluginBase
)
51 BEGIN_EVENT_TABLE( cbBarDragPlugin
, cbPluginBase
)
53 //EVT_PL_LEFT_DOWN ( cbBarDragPlugin::OnLButtonDown )
54 EVT_PL_LEFT_UP ( cbBarDragPlugin::OnLButtonUp
)
55 EVT_PL_MOTION ( cbBarDragPlugin::OnMouseMove
)
56 EVT_PL_DRAW_HINT_RECT ( cbBarDragPlugin::OnDrawHintRect
)
57 EVT_PL_START_BAR_DRAGGING ( cbBarDragPlugin::OnStartBarDragging
)
58 EVT_PL_LEFT_DCLICK ( cbBarDragPlugin::OnLDblClick
)
62 cbBarDragPlugin::cbBarDragPlugin(void)
64 : mBarDragStarted ( false ),
68 mpDraggedBar ( NULL
),
69 mInClientHintBorder( 4 )
72 cbBarDragPlugin::cbBarDragPlugin( wxFrameLayout
* pPanel
, int paneMask
)
74 : cbPluginBase( pPanel
, paneMask
),
76 mBarDragStarted ( false ),
80 mpDraggedBar ( NULL
),
81 mInClientHintBorder( 4 )
84 cbBarDragPlugin::~cbBarDragPlugin()
89 // helper methods (protected)
91 // clips (top/bottom) or (right/left) edges against the frame's bounding rect.
93 void do_clip_edges( int len
, int& rectPos
, int& rectLen
)
103 if ( rectPos
> len
-1 )
109 if ( rectPos
+ rectLen
- 1 > len
)
110 rectLen
-= (rectPos
+ rectLen
) - len
+ 1;
113 void cbBarDragPlugin::ClipRectInFrame( wxRect
& rect
)
116 mpLayout
->GetParentFrame().GetClientSize( &w
, &h
);
118 do_clip_edges( w
, rect
.x
, rect
.width
);
119 do_clip_edges( h
, rect
.y
, rect
.height
);
122 void cbBarDragPlugin::ClipPosInFrame( wxPoint
& pos
)
125 mpLayout
->GetParentFrame().GetClientSize( &w
, &h
);
137 void cbBarDragPlugin::AdjustHintRect( wxPoint
& mousePos
)
139 mHintRect
.x
= mousePos
.x
- mMouseInRectX
;
140 mHintRect
.y
= mousePos
.y
- mMouseInRectY
;
143 cbDockPane
* cbBarDragPlugin::HitTestPanes( wxRect
& rect
)
145 //wxRect clipped = rect;
147 //ClipRectInFrame( clipped );
149 cbDockPane
** pPanes
= mpLayout
->GetPanesArray();
151 for( int i
= 0; i
!= MAX_PANES
; ++i
)
152 if ( rect_hits_rect( pPanes
[i
]->mBoundsInParent
, rect
) )
158 cbDockPane
* cbBarDragPlugin::HitTestPanes( wxPoint
& pos
)
160 wxPoint clipped
= pos
;
162 //ClipPosInFrame( pos );
164 cbDockPane
** pPanes
= mpLayout
->GetPanesArray();
166 for( int i
= 0; i
!= MAX_PANES
; ++i
)
167 if ( rect_contains_point( pPanes
[i
]->mBoundsInParent
, clipped
.x
, clipped
.y
) )
173 bool cbBarDragPlugin::HitsPane( cbDockPane
* pPane
, wxRect
& rect
)
175 return rect_hits_rect( pPane
->mBoundsInParent
, rect
);
178 int cbBarDragPlugin::GetDistanceToPane( cbDockPane
* pPane
, wxPoint
& mousePos
)
180 wxRect
& bounds
= pPane
->mBoundsInParent
;
182 switch( pPane
->mAlignment
)
184 case FL_ALIGN_TOP
: return mousePos
.y
- ( bounds
.y
+ bounds
.height
);
185 case FL_ALIGN_BOTTOM
: return bounds
.y
- mousePos
.y
;
186 case FL_ALIGN_LEFT
: return mousePos
.x
- ( bounds
.x
+ bounds
.width
);
187 case FL_ALIGN_RIGHT
: return bounds
.x
- mousePos
.x
;
188 default : return 0; // never reached
194 bool cbBarDragPlugin::IsInOtherPane( wxPoint
& mousePos
)
196 cbDockPane
* pPane
= HitTestPanes( mousePos
);
198 if ( pPane
&& pPane
!= mpCurPane
) return true;
202 bool cbBarDragPlugin::IsInClientArea( wxPoint
& mousePos
)
204 return ( HitTestPanes( mousePos
) == NULL
);
207 bool cbBarDragPlugin::IsInClientArea( wxRect
& rect
)
209 return ( HitTestPanes( rect
) == NULL
);
212 void cbBarDragPlugin::CalcOnScreenDims( wxRect
& rect
)
214 if ( !mpCurPane
|| mpDraggedBar
->IsFixed() ) return;
216 wxRect inPane
= rect
;
218 mpCurPane
->FrameToPane( &inPane
);
220 int rowNo
= mpCurPane
->GetRowAt( inPane
.y
, inPane
.y
+ inPane
.height
);
222 bool isMaximized
= ( rowNo
>= (int)mpCurPane
->GetRowList().Count() || rowNo
< 0 );
227 inPane
.width
= mpCurPane
->mPaneWidth
;
229 mpCurPane
->PaneToFrame( &inPane
);
237 static inline void check_upper_overrun( int& pos
, int width
, int mousePos
)
239 if ( mousePos
>= pos
+ width
)
240 pos
= mousePos
- width
/2;
243 static inline void check_lower_overrun( int& pos
, int width
, int mousePos
)
245 if ( mousePos
<= pos
)
246 pos
= mousePos
- width
/2;
249 void cbBarDragPlugin::StickToPane( cbDockPane
* pPane
, wxPoint
& mousePos
)
251 int wInPane
= GetBarWidthInPane ( pPane
);
252 int hInPane
= GetBarHeightInPane( pPane
);
254 // adjsut hint-rect horizontally (in pane's orientation)
256 if ( pPane
->IsHorizontal() )
258 mHintRect
.width
= wInPane
;
259 mHintRect
.height
= hInPane
;
263 mHintRect
.height
= wInPane
;
264 mHintRect
.width
= hInPane
;
267 // adjsut hint-rect vertically (in pane's orientation)
269 wxRect
& bounds
= pPane
->mBoundsInParent
;
271 // true, if hint enters the pane through it's lower edge
273 bool fromLowerEdge
= ( pPane
->IsHorizontal() )
274 ? mousePos
.y
> bounds
.y
275 : mousePos
.x
> bounds
.x
;
277 // NOTE:: about all the below min/max things: they are meant to ensure
278 // that the mouse pointer doesn't overrun (leave) the hint-rectangle
279 // when its dimensions are recalculated upon sticking it to the pane
281 if ( pPane
->IsHorizontal() && fromLowerEdge
)
283 int paneBottomEdgeY
= bounds
.y
+ bounds
.height
;
285 mHintRect
.y
= wxMin( paneBottomEdgeY
, mousePos
.y
);
287 check_lower_overrun( mHintRect
.y
, hInPane
, mousePos
.y
);
291 if ( pPane
->IsHorizontal() && !fromLowerEdge
)
293 int paneTopEdgeY
= bounds
.y
;
295 mHintRect
.y
= wxMax( paneTopEdgeY
- hInPane
, mousePos
.y
- hInPane
);
297 check_upper_overrun( mHintRect
.y
, hInPane
, mousePos
.y
);
300 if ( !pPane
->IsHorizontal() && fromLowerEdge
)
302 int paneRightEdgeX
= bounds
.x
+ bounds
.width
;
304 mHintRect
.x
= wxMin( paneRightEdgeX
, mousePos
.x
);
306 check_lower_overrun( mHintRect
.x
, hInPane
, mousePos
.x
);
309 if ( !pPane
->IsHorizontal() && !fromLowerEdge
)
311 int paneLeftEdgeX
= bounds
.x
;
313 mHintRect
.x
= wxMax( paneLeftEdgeX
- hInPane
, mousePos
.x
- hInPane
);
315 check_upper_overrun( mHintRect
.x
, hInPane
, mousePos
.x
);
318 mMouseInRectX
= mousePos
.x
- mHintRect
.x
;
319 mMouseInRectY
= mousePos
.y
- mHintRect
.y
;
321 mpCurPane
= pPane
; // memorize pane to which the hint is currently sticked
324 void cbBarDragPlugin::UnstickFromPane( cbDockPane
* pPane
, wxPoint
& mousePos
)
326 // unsticking causes rectangle to get the shape in which
327 // dragged control-bar would be when floated
329 int newWidth
= mpDraggedBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].x
;
330 int newHeight
= mpDraggedBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].y
;
332 wxRect
& flBounds
= mpDraggedBar
->mDimInfo
.mBounds
[wxCBAR_FLOATING
];
334 if ( flBounds
.width
!= -1 )
336 newWidth
= flBounds
.width
;
337 newHeight
= flBounds
.height
;
340 mHintRect
.width
= newWidth
;
341 mHintRect
.height
= newHeight
;
343 wxRect
& bounds
= pPane
->mBoundsInParent
;
345 // true, if hint leaves the pane through it's lower edge
347 bool fromLowerEdge
= ( pPane
->IsHorizontal() )
348 ? mousePos
.y
> bounds
.y
349 : mousePos
.x
> bounds
.x
;
351 // NOTE:: ...all the below min/max things - see comments about it in StickToPane(..)
353 if ( pPane
->IsHorizontal() && fromLowerEdge
)
355 // bool fromLowerEdge = mousePos.y > bounds.y;
357 mHintRect
.y
= wxMax( bounds
.y
+ bounds
.height
+ 1, mousePos
.y
- newHeight
);
359 check_upper_overrun( mHintRect
.y
, newHeight
, mousePos
.y
);
361 // this is how MFC's hint behaves:
363 if ( mMouseInRectX
> newWidth
)
364 mHintRect
.x
= mousePos
.x
- ( newWidth
/ 2 );
367 if ( pPane
->IsHorizontal() && !fromLowerEdge
)
369 mHintRect
.y
= wxMin( bounds
.y
- newHeight
- 1, mousePos
.y
);
373 if ( mMouseInRectX
> newWidth
)
374 mHintRect
.x
= mousePos
.x
- ( newWidth
/ 2 );
376 check_lower_overrun( mHintRect
.y
, newHeight
, mousePos
.y
);
379 if ( !pPane
->IsHorizontal() && fromLowerEdge
)
381 mHintRect
.x
= wxMax( bounds
.x
+ bounds
.width
, mousePos
.x
- newWidth
);
385 if ( mMouseInRectY
> newHeight
)
386 mHintRect
.y
= mousePos
.y
- ( newHeight
/ 2 );
388 check_upper_overrun( mHintRect
.x
, newWidth
, mousePos
.x
);
391 if ( !pPane
->IsHorizontal() && !fromLowerEdge
)
393 mHintRect
.x
= wxMin( bounds
.x
- newWidth
- 1, mousePos
.x
);
397 if ( mMouseInRectY
> newHeight
)
398 mHintRect
.y
= mousePos
.y
- ( newHeight
/ 2 );
400 check_lower_overrun( mHintRect
.x
, newWidth
, mousePos
.x
);
403 mMouseInRectX
= mousePos
.x
- mHintRect
.x
;
404 mMouseInRectY
= mousePos
.y
- mHintRect
.y
;
409 int cbBarDragPlugin::GetBarWidthInPane( cbDockPane
* pPane
)
411 if ( pPane
== mpSrcPane
)
412 return mBarWidthInSrcPane
;
414 // this is how MFC's bars behave:
416 if ( pPane
->IsHorizontal() )
417 return mpDraggedBar
->mDimInfo
.mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].x
;
419 return mpDraggedBar
->mDimInfo
.mSizes
[wxCBAR_DOCKED_VERTICALLY
].x
;
422 int cbBarDragPlugin::GetBarHeightInPane( cbDockPane
* pPane
)
424 if ( pPane
->IsHorizontal() )
425 return mpDraggedBar
->mDimInfo
.mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].y
;
427 return mpDraggedBar
->mDimInfo
.mSizes
[wxCBAR_DOCKED_VERTICALLY
].y
;
430 void cbBarDragPlugin::ShowHint( bool prevWasInClient
)
432 bool wasDocked
= false;
434 if ( mpSrcPane
->mProps
.mRealTimeUpdatesOn
== false )
436 // do heavy calculations first
438 wxRect actualRect
= mHintRect
; // will be adjusted depending on drag-settings
440 if ( mpSrcPane
->mProps
.mExactDockPredictionOn
&& mpCurPane
)
445 mpLayout
->RedockBar( mpDraggedBar
, mHintRect
, mpCurPane
, false );
447 wxASSERT( success
); // DBG::
449 actualRect
= mpDraggedBar
->mBounds
;
451 mpCurPane
->PaneToFrame( &actualRect
);
454 CalcOnScreenDims( actualRect
);
456 // release previous hint
458 if ( mPrevHintRect
.x
!= POS_UNDEFINED
)
460 // erase previous rectangle
462 cbDrawHintRectEvent
evt( mPrevHintRect
, prevWasInClient
, true, false );
464 mpLayout
->FirePluginEvent( evt
);
469 cbDrawHintRectEvent
evt( actualRect
, mpCurPane
== NULL
, false, false );
471 mpLayout
->FirePluginEvent( evt
);
473 mPrevHintRect
= actualRect
;
477 // otherwise, if real-time updates option is ON
479 if ( mpDraggedBar
->mState
!= wxCBAR_FLOATING
&& !mpCurPane
)
481 mpLayout
->SetBarState( mpDraggedBar
, wxCBAR_FLOATING
, true );
484 if ( mpDraggedBar
->mState
== wxCBAR_FLOATING
&& mpCurPane
)
486 mpLayout
->SetBarState( mpDraggedBar
, wxCBAR_DOCKED_HORIZONTALLY
, false );
493 mpLayout
->GetUpdatesManager().OnStartChanges();
497 mpDraggedBar
->mUMgrData
.SetDirty( true );
502 mpLayout
->RedockBar( mpDraggedBar
, mHintRect
, mpCurPane
, false );
504 wxASSERT( success
); // DBG ::
506 mpLayout
->GetUpdatesManager().OnFinishChanges();
507 mpLayout
->GetUpdatesManager().UpdateNow();
511 if ( mpLayout
->mFloatingOn
)
513 // move the top-most floated bar around as user drags the hint
515 mpDraggedBar
->mDimInfo
.mBounds
[ wxCBAR_FLOATING
] = mHintRect
;
517 mpLayout
->ApplyBarProperties( mpDraggedBar
);
523 /*** event handlers ***/
525 void cbBarDragPlugin::OnMouseMove( cbMotionEvent
& event
)
527 // calculate postion in frame's coordiantes
529 if ( !mBarDragStarted
)
531 event
.Skip(); // pass event to the next plugin
535 wxPoint mousePos
= event
.mPos
;
537 event
.mpPane
->PaneToFrame( &mousePos
.x
, &mousePos
.y
);
539 bool prevIsInClient
= ( mpCurPane
== 0 );
541 AdjustHintRect( mousePos
);
543 // if the hint-rect is not "tempted" to any pane yet
545 if ( mpCurPane
== NULL
)
547 cbDockPane
* pPane
= HitTestPanes( mHintRect
);
549 // enable sticking again, if we've left the pane completely
553 if ( mCanStick
&& pPane
&&
554 GetDistanceToPane( pPane
, mousePos
) < GetBarHeightInPane( pPane
) )
555 StickToPane( pPane
, mousePos
);
557 if ( pPane
&& HitTestPanes( mousePos
) == pPane
&& 0 ) // FOR NOW:: disabled
559 StickToPane( pPane
, mousePos
);
563 // otherwise, when rect is now sticked to some of the panes
564 // check if it should still remain in this pane
568 bool mouseInOther
= IsInOtherPane( mousePos
);
572 cbDockPane
* pPane
= HitTestPanes( mousePos
);
574 StickToPane( pPane
, mousePos
);
578 if ( IsInClientArea( mousePos
) )
580 cbDockPane
* pPane
= HitTestPanes( mHintRect
);
583 pPane
!= mpCurPane
&&
584 GetDistanceToPane( pPane
, mousePos
) < GetBarHeightInPane( pPane
) )
585 StickToPane( pPane
, mousePos
);
589 UnstickFromPane( mpCurPane
, mousePos
);
591 // FOR NOW:: disabled, would cause some mess
592 // mCanStick = false; // prevents from sticking to this
593 // pane again, flag is reset when hint-rect
594 // leaves the pane completely
597 if ( GetDistanceToPane( pPane
, mousePos
) > GetBarHeightInPane( pPane
) )
599 if ( !HitsPane( mpCurPane
, mHintRect
) )
601 UnstickFromPane( mpCurPane
, mousePos
);
603 // FOR NOW:: disabled, would cause some mess
604 // mCanStick = false; // prevents from sticking to this
605 // pane again, flag is reset when hint-rect
606 // leaves the pane completely
614 ShowHint( prevIsInClient
);
616 wxCursor
* pPrevCurs
= mpCurCursor
;
620 mpCurCursor
= mpLayout
->mpNormalCursor
;
624 // if floating is off, and we are in the client
625 // area, the cursor will be invalid, otherwise
626 // it will be the normal cursor
628 if (mpLayout
->mFloatingOn
)
630 mpCurCursor
= mpLayout
->mpNormalCursor
;
634 mpCurCursor
= mpLayout
->mpNECursor
;
638 if ( pPrevCurs
!= mpCurCursor
)
639 mpLayout
->GetParentFrame().SetCursor( *mpCurCursor
);
642 void cbBarDragPlugin::OnLButtonDown( cbLeftDownEvent
& event
)
644 if ( mBarDragStarted
)
646 wxMessageBox(wxT("DblClick!"));
652 void cbBarDragPlugin::OnLButtonUp( cbLeftUpEvent
& event
)
654 if ( mBarDragStarted
)
656 if ( mpSrcPane
->mProps
.mRealTimeUpdatesOn
== false )
658 // erase current rectangle, and finsih on-screen drawing session
660 cbDrawHintRectEvent
evt( mPrevHintRect
, mpCurPane
== NULL
, true, true );
662 mpLayout
->FirePluginEvent( evt
);
664 if ( mpCurPane
!= NULL
)
666 if ( mpSrcPane
->mProps
.mExactDockPredictionOn
)
668 mpLayout
->RedockBar( mpDraggedBar
, mHintRect
, mpCurPane
, false );
670 mpLayout
->GetUpdatesManager().OnFinishChanges();
671 mpLayout
->GetUpdatesManager().UpdateNow();
675 if (mpDraggedBar
->mState
== wxCBAR_FLOATING
)
677 mpLayout
->SetBarState( mpDraggedBar
, wxCBAR_DOCKED_HORIZONTALLY
, true);
680 mpLayout
->RedockBar( mpDraggedBar
, mHintRect
, mpCurPane
);
685 if (mpDraggedBar
->mState
!= wxCBAR_FLOATING
)
687 mpLayout
->SetBarState(mpDraggedBar
, wxCBAR_FLOATING
, true);
690 mpDraggedBar
->mDimInfo
.mBounds
[ wxCBAR_FLOATING
] = mHintRect
;
691 mpLayout
->ApplyBarProperties( mpDraggedBar
);
695 mHintRect
.width
= -1;
697 // In Windows, at least, the frame needs to have a null cursor
698 // else child windows (such as text windows) inherit the cursor
700 mpLayout
->GetParentFrame().SetCursor( wxNullCursor
);
702 mpLayout
->GetParentFrame().SetCursor( *mpLayout
->mpNormalCursor
);
705 mpLayout
->ReleaseEventsFromPane( event
.mpPane
);
706 mpLayout
->ReleaseEventsFromPlugin( this );
708 mBarDragStarted
= false;
710 if ( mBarWasFloating
&& mpDraggedBar
->mState
!= wxCBAR_FLOATING
)
712 // save bar's floating position before it was docked
714 mpDraggedBar
->mDimInfo
.mBounds
[ wxCBAR_FLOATING
] = mFloatedBarBounds
;
718 event
.Skip(); // pass event to the next plugin
721 void cbBarDragPlugin::OnLDblClick( cbLeftDClickEvent
& event
)
723 int avoidCompilerWarning
= 1;
724 if ( avoidCompilerWarning
)
726 cbBarInfo
* pHittedBar
;
729 if ( event
.mpPane
->HitTestPaneItems( event
.mPos
, // in pane's coordiantes
731 &pHittedBar
) == CB_BAR_CONTENT_HITTED
734 mpLayout
->SetBarState( pHittedBar
, wxCBAR_FLOATING
, true );
736 mpLayout
->RepositionFloatedBar( pHittedBar
);
738 return; // event is "eaten" by this plugin
741 mBarDragStarted
= false;
746 //wxMessageBox("Hi, dblclick arrived!");
749 void cbBarDragPlugin::OnStartBarDragging( cbStartBarDraggingEvent
& event
)
751 mpDraggedBar
= event
.mpBar
;
752 mpSrcPane
= event
.mpPane
;
754 mpLayout
->CaptureEventsForPane( event
.mpPane
);
755 mpLayout
->CaptureEventsForPlugin( this );
757 mpLayout
->GetParentFrame().SetCursor( *mpLayout
->mpNormalCursor
);
759 mBarDragStarted
= true;
761 wxRect inParent
= mpDraggedBar
->mBounds
;
763 mBarWasFloating
= mpDraggedBar
->mState
== wxCBAR_FLOATING
;
765 if ( mBarWasFloating
)
767 inParent
= mpDraggedBar
->mDimInfo
.mBounds
[ wxCBAR_FLOATING
];
768 mFloatedBarBounds
= inParent
;
771 event
.mpPane
->PaneToFrame( &inParent
);
773 mHintRect
.x
= POS_UNDEFINED
;
775 mHintRect
.width
= inParent
.width
;
776 mHintRect
.height
= inParent
.height
;
778 mMouseInRectX
= event
.mPos
.x
- inParent
.x
;
779 mMouseInRectY
= event
.mPos
.y
- inParent
.y
;
781 mpSrcPane
= event
.mpPane
;
783 if ( mpDraggedBar
->mState
== wxCBAR_FLOATING
)
787 mpCurPane
= event
.mpPane
;
789 mPrevHintRect
.x
= POS_UNDEFINED
;
791 mCanStick
= false; // we're not stuck into any pane now -
792 // there's nowhere to "stick-twice"
794 mBarWidthInSrcPane
= mpDraggedBar
->mDimInfo
.mSizes
[ mpDraggedBar
->mState
].x
;
796 if ( mpSrcPane
->mProps
.mRealTimeUpdatesOn
== false &&
797 mpSrcPane
->mProps
.mExactDockPredictionOn
)
798 mpLayout
->GetUpdatesManager().OnStartChanges(); // capture initial state of layout
800 // simulate the first mouse movement
802 int x
= event
.mPos
.x
, y
= event
.mPos
.y
;
803 mpSrcPane
->FrameToPane( &x
, &y
);
806 cbMotionEvent
motionEvt( pt
, event
.mpPane
);
807 this->OnMouseMove( motionEvt
);
809 return; // event is "eaten" by this plugin
812 /*** on-screen hint-tracking related methods ***/
814 void cbBarDragPlugin::OnDrawHintRect( cbDrawHintRectEvent
& event
)
816 if ( !mpScrDc
) StartTracking();
818 DoDrawHintRect( event
.mRect
, event
.mIsInClient
);
820 if ( event
.mLastTime
)
824 #define _IMG_A 0xAA // Note: modified from _A to _IMG_A, _A was already defined (cygwin)
825 #define _IMG_B 0x00 // Note: modified from _B to _IMG_A, _B was already defined (cygwin)
826 #define _IMG_C 0x55 // Note: modified from _C to _IMG_C, for consistency reasons.
827 #define _IMG_D 0x00 // Note: modified from _D to _IMG_D, for consistency reasons.
831 static const unsigned char _gCheckerImg
[16] = { _IMG_A
,_IMG_B
,_IMG_C
,_IMG_D
,
832 _IMG_A
,_IMG_B
,_IMG_C
,_IMG_D
,
833 _IMG_A
,_IMG_B
,_IMG_C
,_IMG_D
,
834 _IMG_A
,_IMG_B
,_IMG_C
,_IMG_D
837 void cbBarDragPlugin::StartTracking()
839 mpScrDc
= new wxScreenDC
;
841 wxScreenDC::StartDrawingOnTop(&mpLayout
->GetParentFrame());
844 void cbBarDragPlugin::DoDrawHintRect( wxRect
& rect
, bool isInClientRect
)
848 RectToScr( rect
, scrRect
);
850 int prevLF
= mpScrDc
->GetLogicalFunction();
852 mpScrDc
->SetLogicalFunction( wxINVERT
);
854 if ( isInClientRect
)
856 // BUG BUG BUG (wx):: somehow stippled brush works only
857 // when the bitmap created on stack, not
858 // as a member of the class
860 wxBitmap
checker( (const char*)_gCheckerImg
, 8,8 );
862 wxBrush
checkerBrush( checker
);
864 mpScrDc
->SetPen( mpLayout
->mNullPen
);
865 mpScrDc
->SetBrush( checkerBrush
);
867 int half
= mInClientHintBorder
/ 2;
869 mpScrDc
->DrawRectangle( scrRect
.x
- half
, scrRect
.y
- half
,
870 scrRect
.width
+ 2*half
, mInClientHintBorder
);
872 mpScrDc
->DrawRectangle( scrRect
.x
- half
, scrRect
.y
+ scrRect
.height
- half
,
873 scrRect
.width
+ 2*half
, mInClientHintBorder
);
875 mpScrDc
->DrawRectangle( scrRect
.x
- half
, scrRect
.y
+ half
- 1,
876 mInClientHintBorder
, scrRect
.height
- 2*half
+ 2);
878 mpScrDc
->DrawRectangle( scrRect
.x
+ scrRect
.width
- half
,
879 scrRect
.y
+ half
- 1,
880 mInClientHintBorder
, scrRect
.height
- 2*half
+ 2);
882 mpScrDc
->SetBrush( wxNullBrush
);
886 mpScrDc
->SetPen( mpLayout
->mBlackPen
);
888 mpScrDc
->DrawLine( scrRect
.x
, scrRect
.y
,
889 scrRect
.x
+ scrRect
.width
, scrRect
.y
);
891 mpScrDc
->DrawLine( scrRect
.x
, scrRect
.y
+ 1,
892 scrRect
.x
, scrRect
.y
+ scrRect
.height
);
894 mpScrDc
->DrawLine( scrRect
.x
+1, scrRect
.y
+ scrRect
.height
,
895 scrRect
.x
+ scrRect
.width
, scrRect
.y
+ scrRect
.height
);
897 mpScrDc
->DrawLine( scrRect
.x
+ scrRect
.width
, scrRect
.y
,
898 scrRect
.x
+ scrRect
.width
, scrRect
.y
+ scrRect
.height
+ 1);
901 mpScrDc
->SetLogicalFunction( prevLF
);
904 void cbBarDragPlugin::DrawHintRect ( wxRect
& rect
, bool isInClientRect
)
906 DoDrawHintRect( rect
, isInClientRect
);
909 void cbBarDragPlugin::EraseHintRect( wxRect
& rect
, bool isInClientRect
)
911 DoDrawHintRect( rect
, isInClientRect
);
914 void cbBarDragPlugin::FinishTracking()
916 wxScreenDC::EndDrawingOnTop();
923 void cbBarDragPlugin::RectToScr( wxRect
& frameRect
, wxRect
& scrRect
)
927 int x
= frameRect
.x
, y
= frameRect
.y
;
929 mpLayout
->GetParentFrame().ClientToScreen( &x
, &y
);