1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Contrib. demo
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleksandras Gluchovas
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "bardragpl.h"
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
28 #include "bardragpl.h"
30 #define POS_UNDEFINED -32768
32 // helpers, FOR NOW:: static
34 static inline bool rect_hits_rect( const wxRect
& r1
, const wxRect
& r2
)
36 if ( ( r2
.x
>= r1
.x
&& r2
.x
<= r1
.x
+ r1
.width
) ||
37 ( r1
.x
>= r2
.x
&& r1
.x
<= r2
.x
+ r2
.width
) )
39 if ( ( r2
.y
>= r1
.y
&& r2
.y
<= r1
.y
+ r1
.height
) ||
40 ( r1
.y
>= r2
.y
&& r1
.y
<= r2
.y
+ r2
.height
) )
47 static inline bool rect_contains_point( const wxRect
& rect
, int x
, int y
)
49 return ( x
>= rect
.x
&&
51 x
< rect
.x
+ rect
.width
&&
52 y
< rect
.y
+ rect
.height
);
55 /***** Implementation for class cbBarDragPlugin *****/
57 IMPLEMENT_DYNAMIC_CLASS( cbBarDragPlugin
, cbPluginBase
)
59 BEGIN_EVENT_TABLE( cbBarDragPlugin
, cbPluginBase
)
61 //EVT_PL_LEFT_DOWN ( cbBarDragPlugin::OnLButtonDown )
62 EVT_PL_LEFT_UP ( cbBarDragPlugin::OnLButtonUp
)
63 EVT_PL_MOTION ( cbBarDragPlugin::OnMouseMove
)
64 EVT_PL_DRAW_HINT_RECT ( cbBarDragPlugin::OnDrawHintRect
)
65 EVT_PL_START_BAR_DRAGGING ( cbBarDragPlugin::OnStartBarDragging
)
66 EVT_PL_LEFT_DCLICK ( cbBarDragPlugin::OnLDblClick
)
70 cbBarDragPlugin::cbBarDragPlugin(void)
72 : mBarDragStarted ( FALSE
),
74 mpDraggedBar ( NULL
),
75 mInClientHintBorder( 4 ),
80 cbBarDragPlugin::cbBarDragPlugin( wxFrameLayout
* pPanel
, int paneMask
)
82 : cbPluginBase( pPanel
, paneMask
),
84 mBarDragStarted ( FALSE
),
86 mpDraggedBar ( NULL
),
87 mInClientHintBorder( 4 ),
92 cbBarDragPlugin::~cbBarDragPlugin()
97 // helper methods (protected)
99 // clips (top/bottom) or (right/left) edges against the frame's bounding rect.
101 void do_clip_edges( int len
, long& rectPos
, long& rectLen
)
107 if ( rectLen
< 0 ) rectLen
= 1;
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
);
135 if ( pos
.x
< 0 ) pos
.x
= 0;
136 if ( pos
.y
< 0 ) pos
.y
= 0;
137 if ( pos
.x
> w
) pos
.x
= w
-1;
138 if ( pos
.y
> h
) pos
.y
= h
-1;
141 void cbBarDragPlugin::AdjustHintRect( wxPoint
& mousePos
)
143 mHintRect
.x
= mousePos
.x
- mMouseInRectX
;
144 mHintRect
.y
= mousePos
.y
- mMouseInRectY
;
147 cbDockPane
* cbBarDragPlugin::HitTestPanes( wxRect
& rect
)
149 //wxRect clipped = rect;
151 //ClipRectInFrame( clipped );
153 cbDockPane
** pPanes
= mpLayout
->GetPanesArray();
155 for( int i
= 0; i
!= MAX_PANES
; ++i
)
157 if ( rect_hits_rect( pPanes
[i
]->mBoundsInParent
, rect
) )
164 cbDockPane
* cbBarDragPlugin::HitTestPanes( wxPoint
& pos
)
166 wxPoint clipped
= pos
;
168 //ClipPosInFrame( pos );
170 cbDockPane
** pPanes
= mpLayout
->GetPanesArray();
172 for( int i
= 0; i
!= MAX_PANES
; ++i
)
174 if ( rect_contains_point( pPanes
[i
]->mBoundsInParent
, clipped
.x
, clipped
.y
) )
181 bool cbBarDragPlugin::HitsPane( cbDockPane
* pPane
, wxRect
& rect
)
183 return rect_hits_rect( pPane
->mBoundsInParent
, rect
);
186 int cbBarDragPlugin::GetDistanceToPane( cbDockPane
* pPane
, wxPoint
& mousePos
)
188 wxRect
& bounds
= pPane
->mBoundsInParent
;
190 switch( pPane
->mAlignment
)
192 case wxTOP
: return mousePos
.y
- ( bounds
.y
+ bounds
.height
);
194 case wxBOTTOM
: return bounds
.y
- mousePos
.y
;
196 case wxLEFT
: return mousePos
.x
- ( bounds
.x
+ bounds
.width
);
198 case wxRIGHT
: return bounds
.x
- mousePos
.x
;
200 default : return 0; // never reached
206 bool cbBarDragPlugin::IsInOtherPane( wxPoint
& mousePos
)
208 cbDockPane
* pPane
= HitTestPanes( mousePos
);
210 if ( pPane
&& pPane
!= mpCurPane
) return TRUE
;
214 bool cbBarDragPlugin::IsInClientArea( wxPoint
& mousePos
)
216 return ( HitTestPanes( mousePos
) == NULL
);
219 bool cbBarDragPlugin::IsInClientArea( wxRect
& rect
)
221 return ( HitTestPanes( rect
) == NULL
);
224 void cbBarDragPlugin::CalcOnScreenDims( wxRect
& rect
)
226 if ( !mpCurPane
|| mpDraggedBar
->IsFixed() ) return;
228 wxRect inPane
= rect
;
230 mpCurPane
->FrameToPane( &inPane
);
232 int rowNo
= mpCurPane
->GetRowAt( inPane
.y
, inPane
.y
+ inPane
.height
);
234 bool isMaximized
= ( rowNo
>= (int)mpCurPane
->GetRowList().Count() || rowNo
< 0 );
239 inPane
.width
= mpCurPane
->mPaneWidth
;
241 mpCurPane
->PaneToFrame( &inPane
);
249 static inline void check_upper_overrun( long& pos
, int width
, int mousePos
)
251 if ( mousePos
>= pos
+ width
)
253 pos
= mousePos
- width
/2;
256 static inline void check_lower_overrun( long& pos
, int width
, int mousePos
)
258 if ( mousePos
<= pos
)
260 pos
= mousePos
- width
/2;
263 void cbBarDragPlugin::StickToPane( cbDockPane
* pPane
, wxPoint
& mousePos
)
265 int wInPane
= GetBarWidthInPane ( pPane
);
266 int hInPane
= GetBarHeightInPane( pPane
);
268 // adjsut hint-rect horizontally (in pane's orientation)
270 if ( pPane
->IsHorizontal() )
272 mHintRect
.width
= wInPane
;
273 mHintRect
.height
= hInPane
;
277 mHintRect
.height
= wInPane
;
278 mHintRect
.width
= hInPane
;
281 // adjsut hint-rect vertically (in pane's orientation)
283 wxRect
& bounds
= pPane
->mBoundsInParent
;
285 // TRUE, if hint enters the pane through it's lower edge
287 bool fromLowerEdge
= ( pPane
->IsHorizontal() )
288 ? mousePos
.y
> bounds
.y
289 : mousePos
.x
> bounds
.x
;
291 // NOTE:: about all the below min/max things: they are ment to ensure
292 // that mouse pointer doesn't overrun (leave) the hint-rectangle
293 // when dimensions it's are recalculated upon sticking it to the pane
295 if ( pPane
->IsHorizontal() && fromLowerEdge
)
297 int paneBottomEdgeY
= bounds
.y
+ bounds
.height
;
299 mHintRect
.y
= wxMin( paneBottomEdgeY
, mousePos
.y
);
301 check_lower_overrun( mHintRect
.y
, hInPane
, mousePos
.y
);
305 if ( pPane
->IsHorizontal() && !fromLowerEdge
)
307 int paneTopEdgeY
= bounds
.y
;
309 mHintRect
.y
= wxMax( paneTopEdgeY
- hInPane
, mousePos
.y
- hInPane
);
311 check_upper_overrun( mHintRect
.y
, hInPane
, mousePos
.y
);
314 if ( !pPane
->IsHorizontal() && fromLowerEdge
)
316 int paneRightEdgeX
= bounds
.x
+ bounds
.width
;
318 mHintRect
.x
= wxMin( paneRightEdgeX
, mousePos
.x
);
320 check_lower_overrun( mHintRect
.x
, hInPane
, mousePos
.x
);
323 if ( !pPane
->IsHorizontal() && !fromLowerEdge
)
325 int paneLeftEdgeX
= bounds
.x
;
327 mHintRect
.x
= wxMax( paneLeftEdgeX
- hInPane
, mousePos
.x
- hInPane
);
329 check_upper_overrun( mHintRect
.x
, hInPane
, mousePos
.x
);
332 mMouseInRectX
= mousePos
.x
- mHintRect
.x
;
333 mMouseInRectY
= mousePos
.y
- mHintRect
.y
;
335 mpCurPane
= pPane
; // memorize pane to which the hint is currently sticked
338 void cbBarDragPlugin::UnstickFromPane( cbDockPane
* pPane
, wxPoint
& mousePos
)
340 // unsticking causes rectangle to get the shape, in which
341 // dragged control-bar would be when floated
344 int newWidth
= mpDraggedBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].x
;
345 int newHeight
= mpDraggedBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].y
;
347 wxRect
& flBounds
= mpDraggedBar
->mDimInfo
.mBounds
[wxCBAR_FLOATING
];
349 if ( flBounds
.width
!= -1 )
351 newWidth
= flBounds
.width
;
352 newHeight
= flBounds
.height
;
355 mHintRect
.width
= newWidth
;
356 mHintRect
.height
= newHeight
;
358 wxRect
& bounds
= pPane
->mBoundsInParent
;
360 // TRUE, if hint leaves the pane through it's lower edge
362 bool fromLowerEdge
= ( pPane
->IsHorizontal() )
363 ? mousePos
.y
> bounds
.y
364 : mousePos
.x
> bounds
.x
;
366 // NOTE:: ...all the below min/max things - see comments about it in StickToPane(..)
368 if ( pPane
->IsHorizontal() && fromLowerEdge
)
370 bool fromLowerEdge
= mousePos
.y
> bounds
.y
;
372 mHintRect
.y
= wxMax( bounds
.y
+ bounds
.height
+ 1, mousePos
.y
- newHeight
);
374 check_upper_overrun( mHintRect
.y
, newHeight
, mousePos
.y
);
376 // this is how MFC's hint behaves:
378 if ( mMouseInRectX
> newWidth
)
380 mHintRect
.x
= mousePos
.x
- ( newWidth
/ 2 );
383 if ( pPane
->IsHorizontal() && !fromLowerEdge
)
385 mHintRect
.y
= wxMin( bounds
.y
- newHeight
- 1, mousePos
.y
);
389 if ( mMouseInRectX
> newWidth
)
391 mHintRect
.x
= mousePos
.x
- ( newWidth
/ 2 );
393 check_lower_overrun( mHintRect
.y
, newHeight
, mousePos
.y
);
396 if ( !pPane
->IsHorizontal() && fromLowerEdge
)
398 mHintRect
.x
= wxMax( bounds
.x
+ bounds
.width
, mousePos
.x
- newWidth
);
402 if ( mMouseInRectY
> newHeight
)
404 mHintRect
.y
= mousePos
.y
- ( newHeight
/ 2 );
406 check_upper_overrun( mHintRect
.x
, newWidth
, mousePos
.x
);
409 if ( !pPane
->IsHorizontal() && !fromLowerEdge
)
411 mHintRect
.x
= wxMin( bounds
.x
- newWidth
- 1, mousePos
.x
);
415 if ( mMouseInRectY
> newHeight
)
417 mHintRect
.y
= mousePos
.y
- ( newHeight
/ 2 );
419 check_lower_overrun( mHintRect
.x
, newWidth
, mousePos
.x
);
422 mMouseInRectX
= mousePos
.x
- mHintRect
.x
;
423 mMouseInRectY
= mousePos
.y
- mHintRect
.y
;
428 int cbBarDragPlugin::GetBarWidthInPane( cbDockPane
* pPane
)
430 if ( pPane
== mpSrcPane
)
432 return mBarWidthInSrcPane
;
434 // this is how MFC's bars behave:
436 if ( pPane
->IsHorizontal() )
438 return mpDraggedBar
->mDimInfo
.mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].x
;
440 return mpDraggedBar
->mDimInfo
.mSizes
[wxCBAR_DOCKED_VERTICALLY
].x
;
443 int cbBarDragPlugin::GetBarHeightInPane( cbDockPane
* pPane
)
445 if ( pPane
->IsHorizontal() )
447 return mpDraggedBar
->mDimInfo
.mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].y
;
449 return mpDraggedBar
->mDimInfo
.mSizes
[wxCBAR_DOCKED_VERTICALLY
].y
;
452 void cbBarDragPlugin::ShowHint( bool prevWasInClient
)
454 bool wasDocked
= FALSE
;
456 if ( mpDraggedBar
->mState
!= wxCBAR_FLOATING
&& !mpCurPane
)
458 mpLayout
->SetBarState( mpDraggedBar
, wxCBAR_FLOATING
, TRUE
);
461 if ( mpDraggedBar
->mState
== wxCBAR_FLOATING
&& mpCurPane
)
463 mpLayout
->SetBarState( mpDraggedBar
, wxCBAR_DOCKED_HORIZONTALLY
, FALSE
);
468 if ( mpSrcPane
->mProps
.mRealTimeUpdatesOn
== FALSE
)
470 // do hevy calculations first
472 wxRect actualRect
= mHintRect
; // will be adjusted depending on drag-settings
474 if ( mpSrcPane
->mProps
.mExactDockPredictionOn
&& mpCurPane
)
476 bool success
= mpLayout
->RedockBar( mpDraggedBar
, mHintRect
, mpCurPane
, FALSE
);
478 wxASSERT( success
); // DBG::
480 actualRect
= mpDraggedBar
->mBounds
;
482 mpCurPane
->PaneToFrame( &actualRect
);
485 CalcOnScreenDims( actualRect
);
487 // release previouse hint
489 if ( mPrevHintRect
.x
!= POS_UNDEFINED
)
491 // erase previouse rectangle
493 cbDrawHintRectEvent
evt( mPrevHintRect
, prevWasInClient
, TRUE
, FALSE
);
495 mpLayout
->FirePluginEvent( evt
);
500 cbDrawHintRectEvent
evt( actualRect
, mpCurPane
== NULL
, FALSE
, FALSE
);
502 mpLayout
->FirePluginEvent( evt
);
504 mPrevHintRect
= actualRect
;
508 // otherwise, if real-time updates option is ON
512 mpLayout
->GetUpdatesManager().OnStartChanges();
516 mpDraggedBar
->mUMgrData
.SetDirty( TRUE
);
518 bool success
= mpLayout
->RedockBar( mpDraggedBar
, mHintRect
, mpCurPane
, FALSE
);
520 wxASSERT( success
); // DBG ::
522 mpLayout
->GetUpdatesManager().OnFinishChanges();
523 mpLayout
->GetUpdatesManager().UpdateNow();
527 if ( mpLayout
->mFloatingOn
)
529 // move the top-most floated bar around as user drags the hint
531 mpDraggedBar
->mDimInfo
.mBounds
[ wxCBAR_FLOATING
] = mHintRect
;
533 mpLayout
->ApplyBarProperties( mpDraggedBar
);
539 /*** event handlers ***/
541 void cbBarDragPlugin::OnMouseMove( cbMotionEvent
& event
)
543 // calculate postion in frame's coordiantes
545 if ( !mBarDragStarted
)
547 event
.Skip(); // pass event to the next plugin
551 wxPoint mousePos
= event
.mPos
;
553 event
.mpPane
->PaneToFrame( &mousePos
.x
, &mousePos
.y
);
555 wxRect prevRect
= mHintRect
;
556 bool prevIsInClient
= ( mpCurPane
== 0 );
558 AdjustHintRect( mousePos
);
560 // if the hint-rect is not "tempted" to any pane yet
562 if ( mpCurPane
== NULL
)
564 cbDockPane
* pPane
= HitTestPanes( mHintRect
);
568 // enable sticking again, if we've left the pane completely
571 if ( mCanStick
&& pPane
&&
572 GetDistanceToPane( pPane
, mousePos
) < GetBarHeightInPane( pPane
) )
574 StickToPane( pPane
, mousePos
);
576 if ( pPane
&& HitTestPanes( mousePos
) == pPane
&& 0 ) // FOR NOW:: disabled
578 StickToPane( pPane
, mousePos
);
582 // otherwise, when rect is now sticked to some of the panes
583 // check if it should still remain in this pane
587 bool mouseInOther
= IsInOtherPane( mousePos
);
591 cbDockPane
* pPane
= HitTestPanes( mousePos
);
593 StickToPane( pPane
, mousePos
);
597 if ( IsInClientArea( mousePos
) )
599 cbDockPane
* pPane
= HitTestPanes( mHintRect
);
602 pPane
!= mpCurPane
&&
603 GetDistanceToPane( pPane
, mousePos
) < GetBarHeightInPane( pPane
) )
605 StickToPane( pPane
, mousePos
);
609 UnstickFromPane( mpCurPane
, mousePos
);
611 // FOR NOW:: disabled, would cause some mess
612 //mCanStick = FALSE; // prevents from sticking to this
613 // pane again, flag is reset when hint-rect
614 // leaves the pane completely
617 if ( GetDistanceToPane( pPane
, mousePos
) > GetBarHeightInPane( pPane
) )
619 if ( !HitsPane( mpCurPane
, mHintRect
) )
621 UnstickFromPane( mpCurPane
, mousePos
);
623 // FOR NOW:: disabled, would cause some mess
624 //mCanStick = FALSE; // prevents from sticking to this
625 // pane again, flag is reset when hint-rect
626 // leaves the pane completely
637 ShowHint( prevIsInClient
);
639 wxCursor
* pPrevCurs
= mpCurCursor
;
643 mpCurCursor
= mpLayout
->mpDragCursor
;
646 if ( mpLayout
->mFloatingOn
&& mpSrcPane
->mProps
.mRealTimeUpdatesOn
)
648 mpCurCursor
= mpLayout
->mpDragCursor
;
650 mpCurCursor
= mpLayout
->mpNECursor
;
653 if ( pPrevCurs
!= mpCurCursor
)
655 mpLayout
->GetParentFrame().SetCursor( *mpCurCursor
);
658 void cbBarDragPlugin::OnLButtonDown( cbLeftDownEvent
& event
)
660 if ( mBarDragStarted
)
662 wxMessageBox("DblClick!");
668 void cbBarDragPlugin::OnLButtonUp( cbLeftUpEvent
& event
)
670 if ( mBarDragStarted
)
672 if ( mpSrcPane
->mProps
.mRealTimeUpdatesOn
== FALSE
)
674 // erase current rectangle, and finsih on-screen drawing session
676 cbDrawHintRectEvent
evt( mPrevHintRect
, mpCurPane
== NULL
, TRUE
, TRUE
);
678 mpLayout
->FirePluginEvent( evt
);
680 if ( mpCurPane
!= NULL
)
682 if ( mpSrcPane
->mProps
.mExactDockPredictionOn
)
684 mpLayout
->RedockBar( mpDraggedBar
, mHintRect
, mpCurPane
, FALSE
);
686 mpLayout
->GetUpdatesManager().OnFinishChanges();
687 mpLayout
->GetUpdatesManager().UpdateNow();
690 mpLayout
->RedockBar( mpDraggedBar
, mHintRect
, mpCurPane
);
694 mHintRect
.width
= -1;
696 mpLayout
->GetParentFrame().SetCursor( *mpLayout
->mpNormalCursor
);
698 mpLayout
->ReleaseEventsFromPane( event
.mpPane
);
699 mpLayout
->ReleaseEventsFromPlugin( this );
701 mBarDragStarted
= FALSE
;
703 if ( mBarWasFloating
&& mpDraggedBar
->mState
!= wxCBAR_FLOATING
)
705 // save bar's floating position before it was docked
707 mpDraggedBar
->mDimInfo
.mBounds
[ wxCBAR_FLOATING
] = mFloatedBarBounds
;
711 event
.Skip(); // pass event to the next plugin
714 void cbBarDragPlugin::OnLDblClick( cbLeftDClickEvent
& event
)
718 cbBarInfo
* pHittedBar
;
721 if ( event
.mpPane
->HitTestPaneItems( event
.mPos
, // in pane's coordiantes
723 &pHittedBar
) == CB_BAR_CONTENT_HITTED
726 mpLayout
->SetBarState( pHittedBar
, wxCBAR_FLOATING
, TRUE
);
728 mpLayout
->RepositionFloatedBar( pHittedBar
);
730 return; // event is "eaten" by this plugin
733 mBarDragStarted
= FALSE
;
738 //wxMessageBox("Hi, dblclick arrived!");
741 void cbBarDragPlugin::OnStartBarDragging( cbStartBarDraggingEvent
& event
)
743 mpDraggedBar
= event
.mpBar
;
744 mpSrcPane
= event
.mpPane
;
746 mpLayout
->CaptureEventsForPane( event
.mpPane
);
747 mpLayout
->CaptureEventsForPlugin( this );
749 mpLayout
->GetParentFrame().SetCursor( *mpLayout
->mpDragCursor
);
751 mBarDragStarted
= TRUE
;
753 wxRect inParent
= mpDraggedBar
->mBounds
;
755 mBarWasFloating
= mpDraggedBar
->mState
== wxCBAR_FLOATING
;
757 if ( mBarWasFloating
)
759 inParent
= mpDraggedBar
->mDimInfo
.mBounds
[ wxCBAR_FLOATING
];
760 mFloatedBarBounds
= inParent
;
763 event
.mpPane
->PaneToFrame( &inParent
);
765 mHintRect
.x
= POS_UNDEFINED
;
767 mHintRect
.width
= inParent
.width
;
768 mHintRect
.height
= inParent
.height
;
770 mMouseInRectX
= event
.mPos
.x
- inParent
.x
;
771 mMouseInRectY
= event
.mPos
.y
- inParent
.y
;
773 mpSrcPane
= event
.mpPane
;
775 if ( mpDraggedBar
->mState
== wxCBAR_FLOATING
)
779 mpCurPane
= event
.mpPane
;
781 mPrevHintRect
.x
= POS_UNDEFINED
;
783 mCanStick
= FALSE
; // we're not stuck into any pane now -
784 // there's nowhere to "stick-twice"
786 mBarWidthInSrcPane
= mpDraggedBar
->mDimInfo
.mSizes
[ mpDraggedBar
->mState
].x
;
788 if ( mpSrcPane
->mProps
.mRealTimeUpdatesOn
== FALSE
&&
789 mpSrcPane
->mProps
.mExactDockPredictionOn
)
791 mpLayout
->GetUpdatesManager().OnStartChanges(); // capture initial state of layout
793 // simulate the first mouse movement
795 long x
= event
.mPos
.x
, y
= event
.mPos
.y
;
797 mpSrcPane
->FrameToPane( &x
, &y
);
799 cbMotionEvent
motionEvt( wxPoint(x
,y
), event
.mpPane
);
802 this->OnMouseMove( motionEvt
);
804 return; // event is "eaten" by this plugin
807 /*** on-screen hint-tracking related methods ***/
809 void cbBarDragPlugin::OnDrawHintRect( cbDrawHintRectEvent
& event
)
811 if ( !mpScrDc
) StartTracking();
813 DoDrawHintRect( event
.mRect
, event
.mIsInClient
);
815 if ( event
.mLastTime
)
827 static const unsigned char _gCheckerImg
[16] = { _A
,_B
,_C
,_D
,
833 void cbBarDragPlugin::StartTracking()
835 mpScrDc
= new wxScreenDC
;
837 wxScreenDC::StartDrawingOnTop(&mpLayout
->GetParentFrame());
840 void cbBarDragPlugin::DoDrawHintRect( wxRect
& rect
, bool isInClientRect
)
844 RectToScr( rect
, scrRect
);
846 int prevLF
= mpScrDc
->GetLogicalFunction();
848 mpScrDc
->SetLogicalFunction( wxXOR
);
850 if ( isInClientRect
)
852 // BUG BUG BUG (wx):: somehow stippled brush works only
853 // when the bitmap created on stack, not
854 // as a member of the class
856 wxBitmap
checker( (const char*)_gCheckerImg
, 8,8 );
858 wxBrush
checkerBrush( checker
);
860 mpScrDc
->SetPen( mpLayout
->mNullPen
);
861 mpScrDc
->SetBrush( checkerBrush
);
863 int half
= mInClientHintBorder
/ 2;
865 mpScrDc
->DrawRectangle( scrRect
.x
- half
, scrRect
.y
- half
,
866 scrRect
.width
+ 2*half
, mInClientHintBorder
);
868 mpScrDc
->DrawRectangle( scrRect
.x
- half
, scrRect
.y
+ scrRect
.height
- half
,
869 scrRect
.width
+ 2*half
, mInClientHintBorder
);
871 mpScrDc
->DrawRectangle( scrRect
.x
- half
, scrRect
.y
+ half
- 1,
872 mInClientHintBorder
, scrRect
.height
- 2*half
+ 2);
874 mpScrDc
->DrawRectangle( scrRect
.x
+ scrRect
.width
- half
,
875 scrRect
.y
+ half
- 1,
876 mInClientHintBorder
, scrRect
.height
- 2*half
+ 2);
878 mpScrDc
->SetBrush( wxNullBrush
);
882 mpScrDc
->SetPen( mpLayout
->mBlackPen
);
884 mpScrDc
->DrawLine( scrRect
.x
, scrRect
.y
,
885 scrRect
.x
+ scrRect
.width
, scrRect
.y
);
887 mpScrDc
->DrawLine( scrRect
.x
, scrRect
.y
+ 1,
888 scrRect
.x
, scrRect
.y
+ scrRect
.height
);
890 mpScrDc
->DrawLine( scrRect
.x
+1, scrRect
.y
+ scrRect
.height
,
891 scrRect
.x
+ scrRect
.width
, scrRect
.y
+ scrRect
.height
);
893 mpScrDc
->DrawLine( scrRect
.x
+ scrRect
.width
, scrRect
.y
,
894 scrRect
.x
+ scrRect
.width
, scrRect
.y
+ scrRect
.height
+ 1);
897 mpScrDc
->SetLogicalFunction( prevLF
);
900 void cbBarDragPlugin::DrawHintRect ( wxRect
& rect
, bool isInClientRect
)
902 DoDrawHintRect( rect
, isInClientRect
);
905 void cbBarDragPlugin::EraseHintRect( wxRect
& rect
, bool isInClientRect
)
907 DoDrawHintRect( rect
, isInClientRect
);
910 void cbBarDragPlugin::FinishTracking()
912 wxScreenDC::EndDrawingOnTop();
919 void cbBarDragPlugin::RectToScr( wxRect
& frameRect
, wxRect
& scrRect
)
923 int x
= frameRect
.x
, y
= frameRect
.y
;
925 mpLayout
->GetParentFrame().ClientToScreen( &x
, &y
);