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
;
459 if ( mpDraggedBar
->mState
!= wxCBAR_FLOATING
&& !mpCurPane
)
461 mpLayout
->SetBarState( mpDraggedBar
, wxCBAR_FLOATING
, TRUE
);
464 if ( mpDraggedBar
->mState
== wxCBAR_FLOATING
&& mpCurPane
)
466 mpLayout
->SetBarState( mpDraggedBar
, wxCBAR_DOCKED_HORIZONTALLY
, FALSE
);
471 if ( mpSrcPane
->mProps
.mRealTimeUpdatesOn
== FALSE
)
473 // do heavy calculations first
475 wxRect actualRect
= mHintRect
; // will be adjusted depending on drag-settings
477 if ( mpSrcPane
->mProps
.mExactDockPredictionOn
&& mpCurPane
)
479 bool success
= mpLayout
->RedockBar( mpDraggedBar
, mHintRect
, mpCurPane
, FALSE
);
481 wxASSERT( success
); // DBG::
483 actualRect
= mpDraggedBar
->mBounds
;
485 mpCurPane
->PaneToFrame( &actualRect
);
488 CalcOnScreenDims( actualRect
);
490 // release previous hint
492 if ( mPrevHintRect
.x
!= POS_UNDEFINED
)
494 // erase previous rectangle
496 cbDrawHintRectEvent
evt( mPrevHintRect
, prevWasInClient
, TRUE
, FALSE
);
498 mpLayout
->FirePluginEvent( evt
);
503 cbDrawHintRectEvent
evt( actualRect
, mpCurPane
== NULL
, FALSE
, FALSE
);
505 mpLayout
->FirePluginEvent( evt
);
507 mPrevHintRect
= actualRect
;
511 // otherwise, if real-time updates option is ON
515 mpLayout
->GetUpdatesManager().OnStartChanges();
519 mpDraggedBar
->mUMgrData
.SetDirty( TRUE
);
521 bool success
= mpLayout
->RedockBar( mpDraggedBar
, mHintRect
, mpCurPane
, FALSE
);
523 wxASSERT( success
); // DBG ::
525 mpLayout
->GetUpdatesManager().OnFinishChanges();
526 mpLayout
->GetUpdatesManager().UpdateNow();
530 if ( mpLayout
->mFloatingOn
)
532 // move the top-most floated bar around as user drags the hint
534 mpDraggedBar
->mDimInfo
.mBounds
[ wxCBAR_FLOATING
] = mHintRect
;
536 mpLayout
->ApplyBarProperties( mpDraggedBar
);
542 /*** event handlers ***/
544 void cbBarDragPlugin::OnMouseMove( cbMotionEvent
& event
)
546 // calculate postion in frame's coordiantes
548 if ( !mBarDragStarted
)
550 event
.Skip(); // pass event to the next plugin
554 wxPoint mousePos
= event
.mPos
;
556 event
.mpPane
->PaneToFrame( &mousePos
.x
, &mousePos
.y
);
558 bool prevIsInClient
= ( mpCurPane
== 0 );
560 AdjustHintRect( mousePos
);
562 // if the hint-rect is not "tempted" to any pane yet
564 if ( mpCurPane
== NULL
)
566 cbDockPane
* pPane
= HitTestPanes( mHintRect
);
570 // enable sticking again, if we've left the pane completely
573 if ( mCanStick
&& pPane
&&
574 GetDistanceToPane( pPane
, mousePos
) < GetBarHeightInPane( pPane
) )
576 StickToPane( pPane
, mousePos
);
578 if ( pPane
&& HitTestPanes( mousePos
) == pPane
&& 0 ) // FOR NOW:: disabled
580 StickToPane( pPane
, mousePos
);
584 // otherwise, when rect is now sticked to some of the panes
585 // check if it should still remain in this pane
589 bool mouseInOther
= IsInOtherPane( mousePos
);
593 cbDockPane
* pPane
= HitTestPanes( mousePos
);
595 StickToPane( pPane
, mousePos
);
599 if ( IsInClientArea( mousePos
) )
601 cbDockPane
* pPane
= HitTestPanes( mHintRect
);
604 pPane
!= mpCurPane
&&
605 GetDistanceToPane( pPane
, mousePos
) < GetBarHeightInPane( pPane
) )
607 StickToPane( pPane
, mousePos
);
611 UnstickFromPane( mpCurPane
, mousePos
);
613 // FOR NOW:: disabled, would cause some mess
614 //mCanStick = FALSE; // prevents from sticking to this
615 // pane again, flag is reset when hint-rect
616 // leaves the pane completely
619 if ( GetDistanceToPane( pPane
, mousePos
) > GetBarHeightInPane( pPane
) )
621 if ( !HitsPane( mpCurPane
, mHintRect
) )
623 UnstickFromPane( mpCurPane
, mousePos
);
625 // FOR NOW:: disabled, would cause some mess
626 //mCanStick = FALSE; // prevents from sticking to this
627 // pane again, flag is reset when hint-rect
628 // leaves the pane completely
639 ShowHint( prevIsInClient
);
641 wxCursor
* pPrevCurs
= mpCurCursor
;
645 mpCurCursor
= mpLayout
->mpDragCursor
;
648 if ( mpLayout
->mFloatingOn
&& mpSrcPane
->mProps
.mRealTimeUpdatesOn
)
650 mpCurCursor
= mpLayout
->mpDragCursor
;
652 mpCurCursor
= mpLayout
->mpNECursor
;
655 if ( pPrevCurs
!= mpCurCursor
)
657 mpLayout
->GetParentFrame().SetCursor( *mpCurCursor
);
660 void cbBarDragPlugin::OnLButtonDown( cbLeftDownEvent
& event
)
662 if ( mBarDragStarted
)
664 wxMessageBox("DblClick!");
670 void cbBarDragPlugin::OnLButtonUp( cbLeftUpEvent
& event
)
672 if ( mBarDragStarted
)
674 if ( mpSrcPane
->mProps
.mRealTimeUpdatesOn
== FALSE
)
676 // erase current rectangle, and finsih on-screen drawing session
678 cbDrawHintRectEvent
evt( mPrevHintRect
, mpCurPane
== NULL
, TRUE
, TRUE
);
680 mpLayout
->FirePluginEvent( evt
);
682 if ( mpCurPane
!= NULL
)
684 if ( mpSrcPane
->mProps
.mExactDockPredictionOn
)
686 mpLayout
->RedockBar( mpDraggedBar
, mHintRect
, mpCurPane
, FALSE
);
688 mpLayout
->GetUpdatesManager().OnFinishChanges();
689 mpLayout
->GetUpdatesManager().UpdateNow();
692 mpLayout
->RedockBar( mpDraggedBar
, mHintRect
, mpCurPane
);
696 mHintRect
.width
= -1;
698 mpLayout
->GetParentFrame().SetCursor( *mpLayout
->mpNormalCursor
);
700 mpLayout
->ReleaseEventsFromPane( event
.mpPane
);
701 mpLayout
->ReleaseEventsFromPlugin( this );
703 mBarDragStarted
= FALSE
;
705 if ( mBarWasFloating
&& mpDraggedBar
->mState
!= wxCBAR_FLOATING
)
707 // save bar's floating position before it was docked
709 mpDraggedBar
->mDimInfo
.mBounds
[ wxCBAR_FLOATING
] = mFloatedBarBounds
;
713 event
.Skip(); // pass event to the next plugin
716 void cbBarDragPlugin::OnLDblClick( cbLeftDClickEvent
& event
)
718 int avoidCompilerWarning
= 1;
719 if ( avoidCompilerWarning
)
721 cbBarInfo
* pHittedBar
;
724 if ( event
.mpPane
->HitTestPaneItems( event
.mPos
, // in pane's coordiantes
726 &pHittedBar
) == CB_BAR_CONTENT_HITTED
729 mpLayout
->SetBarState( pHittedBar
, wxCBAR_FLOATING
, TRUE
);
731 mpLayout
->RepositionFloatedBar( pHittedBar
);
733 return; // event is "eaten" by this plugin
736 mBarDragStarted
= FALSE
;
741 //wxMessageBox("Hi, dblclick arrived!");
744 void cbBarDragPlugin::OnStartBarDragging( cbStartBarDraggingEvent
& event
)
746 mpDraggedBar
= event
.mpBar
;
747 mpSrcPane
= event
.mpPane
;
749 mpLayout
->CaptureEventsForPane( event
.mpPane
);
750 mpLayout
->CaptureEventsForPlugin( this );
752 mpLayout
->GetParentFrame().SetCursor( *mpLayout
->mpDragCursor
);
754 mBarDragStarted
= TRUE
;
756 wxRect inParent
= mpDraggedBar
->mBounds
;
758 mBarWasFloating
= mpDraggedBar
->mState
== wxCBAR_FLOATING
;
760 if ( mBarWasFloating
)
762 inParent
= mpDraggedBar
->mDimInfo
.mBounds
[ wxCBAR_FLOATING
];
763 mFloatedBarBounds
= inParent
;
766 event
.mpPane
->PaneToFrame( &inParent
);
768 mHintRect
.x
= POS_UNDEFINED
;
770 mHintRect
.width
= inParent
.width
;
771 mHintRect
.height
= inParent
.height
;
773 mMouseInRectX
= event
.mPos
.x
- inParent
.x
;
774 mMouseInRectY
= event
.mPos
.y
- inParent
.y
;
776 mpSrcPane
= event
.mpPane
;
778 if ( mpDraggedBar
->mState
== wxCBAR_FLOATING
)
782 mpCurPane
= event
.mpPane
;
784 mPrevHintRect
.x
= POS_UNDEFINED
;
786 mCanStick
= FALSE
; // we're not stuck into any pane now -
787 // there's nowhere to "stick-twice"
789 mBarWidthInSrcPane
= mpDraggedBar
->mDimInfo
.mSizes
[ mpDraggedBar
->mState
].x
;
791 if ( mpSrcPane
->mProps
.mRealTimeUpdatesOn
== FALSE
&&
792 mpSrcPane
->mProps
.mExactDockPredictionOn
)
794 mpLayout
->GetUpdatesManager().OnStartChanges(); // capture initial state of layout
796 // simulate the first mouse movement
798 int x
= event
.mPos
.x
, y
= event
.mPos
.y
;
800 mpSrcPane
->FrameToPane( &x
, &y
);
802 cbMotionEvent
motionEvt( wxPoint(x
,y
), event
.mpPane
);
805 this->OnMouseMove( motionEvt
);
807 return; // event is "eaten" by this plugin
810 /*** on-screen hint-tracking related methods ***/
812 void cbBarDragPlugin::OnDrawHintRect( cbDrawHintRectEvent
& event
)
814 if ( !mpScrDc
) StartTracking();
816 DoDrawHintRect( event
.mRect
, event
.mIsInClient
);
818 if ( event
.mLastTime
)
823 #define _IMG_A 0xAA // Note: modified from _A to _IMG_A, _A was already defined (cygwin)
824 #define _IMG_B 0x00 // Note: modified from _B to _IMG_A, _B was already defined (cygwin)
825 #define _IMG_C 0x55 // Note: modified from _C to _IMG_C, for consistency reasons.
826 #define _IMG_D 0x00 // Note: modified from _D to _IMG_D, for consistency reasons.
830 static const unsigned char _gCheckerImg
[16] = { _IMG_A
,_IMG_B
,_IMG_C
,_IMG_D
,
831 _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
836 void cbBarDragPlugin::StartTracking()
838 mpScrDc
= new wxScreenDC
;
840 wxScreenDC::StartDrawingOnTop(&mpLayout
->GetParentFrame());
843 void cbBarDragPlugin::DoDrawHintRect( wxRect
& rect
, bool isInClientRect
)
847 RectToScr( rect
, scrRect
);
849 int prevLF
= mpScrDc
->GetLogicalFunction();
851 mpScrDc
->SetLogicalFunction( wxINVERT
);
853 if ( isInClientRect
)
855 // BUG BUG BUG (wx):: somehow stippled brush works only
856 // when the bitmap created on stack, not
857 // as a member of the class
859 wxBitmap
checker( (const char*)_gCheckerImg
, 8,8 );
861 wxBrush
checkerBrush( checker
);
863 mpScrDc
->SetPen( mpLayout
->mNullPen
);
864 mpScrDc
->SetBrush( checkerBrush
);
866 int half
= mInClientHintBorder
/ 2;
868 mpScrDc
->DrawRectangle( scrRect
.x
- half
, scrRect
.y
- half
,
869 scrRect
.width
+ 2*half
, mInClientHintBorder
);
871 mpScrDc
->DrawRectangle( scrRect
.x
- half
, scrRect
.y
+ scrRect
.height
- half
,
872 scrRect
.width
+ 2*half
, mInClientHintBorder
);
874 mpScrDc
->DrawRectangle( scrRect
.x
- half
, scrRect
.y
+ half
- 1,
875 mInClientHintBorder
, scrRect
.height
- 2*half
+ 2);
877 mpScrDc
->DrawRectangle( scrRect
.x
+ scrRect
.width
- half
,
878 scrRect
.y
+ half
- 1,
879 mInClientHintBorder
, scrRect
.height
- 2*half
+ 2);
881 mpScrDc
->SetBrush( wxNullBrush
);
885 mpScrDc
->SetPen( mpLayout
->mBlackPen
);
887 mpScrDc
->DrawLine( scrRect
.x
, scrRect
.y
,
888 scrRect
.x
+ scrRect
.width
, scrRect
.y
);
890 mpScrDc
->DrawLine( scrRect
.x
, scrRect
.y
+ 1,
891 scrRect
.x
, scrRect
.y
+ scrRect
.height
);
893 mpScrDc
->DrawLine( scrRect
.x
+1, scrRect
.y
+ scrRect
.height
,
894 scrRect
.x
+ scrRect
.width
, scrRect
.y
+ scrRect
.height
);
896 mpScrDc
->DrawLine( scrRect
.x
+ scrRect
.width
, scrRect
.y
,
897 scrRect
.x
+ scrRect
.width
, scrRect
.y
+ scrRect
.height
+ 1);
900 mpScrDc
->SetLogicalFunction( prevLF
);
903 void cbBarDragPlugin::DrawHintRect ( wxRect
& rect
, bool isInClientRect
)
905 DoDrawHintRect( rect
, isInClientRect
);
908 void cbBarDragPlugin::EraseHintRect( wxRect
& rect
, bool isInClientRect
)
910 DoDrawHintRect( rect
, isInClientRect
);
913 void cbBarDragPlugin::FinishTracking()
915 wxScreenDC::EndDrawingOnTop();
922 void cbBarDragPlugin::RectToScr( wxRect
& frameRect
, wxRect
& scrRect
)
926 int x
= frameRect
.x
, y
= frameRect
.y
;
928 mpLayout
->GetParentFrame().ClientToScreen( &x
, &y
);