]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/fl/bardragpl.cpp
added the keyboard sample
[wxWidgets.git] / contrib / src / fl / bardragpl.cpp
CommitLineData
8e08b761 1/////////////////////////////////////////////////////////////////////////////
4cbc57f0
JS
2// Name: bardragpl.cpp
3// Purpose: cbBarDragPlugin implementation
8e08b761
JS
4// Author: Aleksandras Gluchovas
5// Modified by:
6// Created: 23/09/98
7// RCS-ID: $Id$
8// Copyright: (c) Aleksandras Gluchovas
4cbc57f0 9// Licence: wxWindows licence
8e08b761
JS
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13 #pragma implementation "bardragpl.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 "wx/fl/bardragpl.h"
28
29#define POS_UNDEFINED -32768
30
31// helpers, FOR NOW:: static
32
33static inline bool rect_hits_rect( const wxRect& r1, const wxRect& r2 )
34{
35 if ( ( r2.x >= r1.x && r2.x <= r1.x + r1.width ) ||
36 ( r1.x >= r2.x && r1.x <= r2.x + r2.width ) )
37
38 if ( ( r2.y >= r1.y && r2.y <= r1.y + r1.height ) ||
39 ( r1.y >= r2.y && r1.y <= r2.y + r2.height ) )
40
41 return TRUE;
42
43 return FALSE;
44}
45
46static inline bool rect_contains_point( const wxRect& rect, int x, int y )
47{
48 return ( x >= rect.x &&
49 y >= rect.y &&
50 x < rect.x + rect.width &&
51 y < rect.y + rect.height );
52}
53
54/***** Implementation for class cbBarDragPlugin *****/
55
56IMPLEMENT_DYNAMIC_CLASS( cbBarDragPlugin, cbPluginBase )
57
58BEGIN_EVENT_TABLE( cbBarDragPlugin, cbPluginBase )
59
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 )
66
67END_EVENT_TABLE()
68
69cbBarDragPlugin::cbBarDragPlugin(void)
70
71 : mBarDragStarted ( FALSE ),
72 mCanStick ( TRUE ),
73 mpScrDc ( NULL ),
74 mpCurCursor ( NULL ),
75 mpDraggedBar ( NULL ),
76 mInClientHintBorder( 4 )
77{}
78
79cbBarDragPlugin::cbBarDragPlugin( wxFrameLayout* pPanel, int paneMask )
80
81 : cbPluginBase( pPanel, paneMask ),
82
83 mBarDragStarted ( FALSE ),
84 mCanStick ( TRUE ),
85 mpScrDc ( NULL ),
86 mpCurCursor ( NULL ),
87 mpDraggedBar ( NULL ),
88 mInClientHintBorder( 4 )
89{}
90
91cbBarDragPlugin::~cbBarDragPlugin()
92{
93 // nothing
94}
95
96// helper methods (protected)
97
98// clips (top/bottom) or (right/left) edges against the frame's bounding rect.
99
100void do_clip_edges( int len, int& rectPos, int& rectLen )
101{
102 if ( rectPos < 0 )
103 {
104 rectLen += rectPos;
105 rectPos = 0;
106 if ( rectLen < 0 )
107 rectLen = 1;
108 }
109 else
110 if ( rectPos > len-1 )
111 {
112 rectPos = len-1;
113 rectLen = 1;
114 }
115 else
116 if ( rectPos + rectLen - 1 > len )
117
118 rectLen -= (rectPos + rectLen) - len + 1;
119}
120
121void cbBarDragPlugin::ClipRectInFrame( wxRect& rect )
122{
123 int w, h;
124 mpLayout->GetParentFrame().GetClientSize( &w, &h );
125
126 do_clip_edges( w, rect.x, rect.width );
127 do_clip_edges( h, rect.y, rect.height );
128}
129
130void cbBarDragPlugin::ClipPosInFrame( wxPoint& pos )
131{
132 int w, h;
133 mpLayout->GetParentFrame().GetClientSize( &w, &h );
134
135 if ( pos.x < 0 )
136 pos.x = 0;
137 if ( pos.y < 0 )
138 pos.y = 0;
139 if ( pos.x > w )
140 pos.x = w-1;
141 if ( pos.y > h )
142 pos.y = h-1;
143}
144
145void cbBarDragPlugin::AdjustHintRect( wxPoint& mousePos )
146{
147 mHintRect.x = mousePos.x - mMouseInRectX;
148 mHintRect.y = mousePos.y - mMouseInRectY;
149}
150
151cbDockPane* cbBarDragPlugin::HitTestPanes( wxRect& rect )
152{
153 //wxRect clipped = rect;
154
155 //ClipRectInFrame( clipped );
156
157 cbDockPane** pPanes = mpLayout->GetPanesArray();
158
159 for( int i = 0; i != MAX_PANES; ++i )
160
161 if ( rect_hits_rect( pPanes[i]->mBoundsInParent, rect ) )
162
163 return pPanes[i];
164
165 return NULL;
166}
167
168cbDockPane* cbBarDragPlugin::HitTestPanes( wxPoint& pos )
169{
170 wxPoint clipped = pos;
171
172 //ClipPosInFrame( pos );
173
174 cbDockPane** pPanes = mpLayout->GetPanesArray();
175
176 for( int i = 0; i != MAX_PANES; ++i )
177
178 if ( rect_contains_point( pPanes[i]->mBoundsInParent, clipped.x, clipped.y ) )
179
180 return pPanes[i];
181
182 return NULL;
183}
184
185bool cbBarDragPlugin::HitsPane( cbDockPane* pPane, wxRect& rect )
186{
187 return rect_hits_rect( pPane->mBoundsInParent, rect );
188}
189
190int cbBarDragPlugin::GetDistanceToPane( cbDockPane* pPane, wxPoint& mousePos )
191{
192 wxRect& bounds = pPane->mBoundsInParent;
193
194 switch( pPane->mAlignment )
195 {
196 case FL_ALIGN_TOP : return mousePos.y - ( bounds.y + bounds.height );
197
198 case FL_ALIGN_BOTTOM : return bounds.y - mousePos.y;
199
200 case FL_ALIGN_LEFT : return mousePos.x - ( bounds.x + bounds.width );
201
202 case FL_ALIGN_RIGHT : return bounds.x - mousePos.x;
203
204 default : return 0; // never reached
205 }
206
207// return 0;
208}
209
210bool cbBarDragPlugin::IsInOtherPane( wxPoint& mousePos )
211{
212 cbDockPane* pPane = HitTestPanes( mousePos );
213
214 if ( pPane && pPane != mpCurPane ) return TRUE;
215 else return FALSE;
216}
217
218bool cbBarDragPlugin::IsInClientArea( wxPoint& mousePos )
219{
220 return ( HitTestPanes( mousePos ) == NULL );
221}
222
223bool cbBarDragPlugin::IsInClientArea( wxRect& rect )
224{
225 return ( HitTestPanes( rect ) == NULL );
226}
227
228void cbBarDragPlugin::CalcOnScreenDims( wxRect& rect )
229{
230 if ( !mpCurPane || mpDraggedBar->IsFixed() ) return;
231
232 wxRect inPane = rect;
233
234 mpCurPane->FrameToPane( &inPane );
235
236 int rowNo = mpCurPane->GetRowAt( inPane.y, inPane.y + inPane.height );
237
238 bool isMaximized = ( rowNo >= (int)mpCurPane->GetRowList().Count() || rowNo < 0 );
239
240 if ( isMaximized )
241 {
242 inPane.x = 0;
243 inPane.width = mpCurPane->mPaneWidth;
244
245 mpCurPane->PaneToFrame( &inPane );
246
247 rect = inPane;
248 }
249}
250
251// helpers
252
253static inline void check_upper_overrun( int& pos, int width, int mousePos )
254{
255 if ( mousePos >= pos + width )
256
257 pos = mousePos - width/2;
258}
259
260static inline void check_lower_overrun( int& pos, int width, int mousePos )
261{
262 if ( mousePos <= pos )
263
264 pos = mousePos - width/2;
265}
266
267void cbBarDragPlugin::StickToPane( cbDockPane* pPane, wxPoint& mousePos )
268{
269 int wInPane = GetBarWidthInPane ( pPane );
270 int hInPane = GetBarHeightInPane( pPane );
271
272 // adjsut hint-rect horizontally (in pane's orientation)
273
274 if ( pPane->IsHorizontal() )
275 {
276 mHintRect.width = wInPane;
277 mHintRect.height = hInPane;
278 }
279 else
280 {
281 mHintRect.height = wInPane;
282 mHintRect.width = hInPane;
283 }
284
285 // adjsut hint-rect vertically (in pane's orientation)
286
287 wxRect& bounds = pPane->mBoundsInParent;
288
289 // TRUE, if hint enters the pane through it's lower edge
290
291 bool fromLowerEdge = ( pPane->IsHorizontal() )
292 ? mousePos.y > bounds.y
293 : mousePos.x > bounds.x;
294
295 // NOTE:: about all the below min/max things: they are meant to ensure
4cbc57f0
JS
296 // that the mouse pointer doesn't overrun (leave) the hint-rectangle
297 // when its dimensions are recalculated upon sticking it to the pane
8e08b761
JS
298
299 if ( pPane->IsHorizontal() && fromLowerEdge )
300 {
301 int paneBottomEdgeY = bounds.y + bounds.height;
302
303 mHintRect.y = wxMin( paneBottomEdgeY, mousePos.y );
304
305 check_lower_overrun( mHintRect.y, hInPane, mousePos.y );
306
307 }
308 else
309 if ( pPane->IsHorizontal() && !fromLowerEdge )
310 {
311 int paneTopEdgeY = bounds.y;
312
313 mHintRect.y = wxMax( paneTopEdgeY - hInPane, mousePos.y - hInPane );
314
315 check_upper_overrun( mHintRect.y, hInPane, mousePos.y );
316 }
317 else
318 if ( !pPane->IsHorizontal() && fromLowerEdge )
319 {
320 int paneRightEdgeX = bounds.x + bounds.width;
321
322 mHintRect.x = wxMin( paneRightEdgeX, mousePos.x );
323
324 check_lower_overrun( mHintRect.x, hInPane, mousePos.x );
325 }
326 else
327 if ( !pPane->IsHorizontal() && !fromLowerEdge )
328 {
329 int paneLeftEdgeX = bounds.x;
330
331 mHintRect.x = wxMax( paneLeftEdgeX - hInPane, mousePos.x - hInPane );
332
333 check_upper_overrun( mHintRect.x, hInPane, mousePos.x );
334 }
335
336 mMouseInRectX = mousePos.x - mHintRect.x;
337 mMouseInRectY = mousePos.y - mHintRect.y;
338
339 mpCurPane = pPane; // memorize pane to which the hint is currently sticked
340}
341
342void cbBarDragPlugin::UnstickFromPane( cbDockPane* pPane, wxPoint& mousePos )
343{
4cbc57f0 344 // unsticking causes rectangle to get the shape in which
8e08b761
JS
345 // dragged control-bar would be when floated
346
8e08b761
JS
347 int newWidth = mpDraggedBar->mDimInfo.mSizes[wxCBAR_FLOATING].x;
348 int newHeight = mpDraggedBar->mDimInfo.mSizes[wxCBAR_FLOATING].y;
349
350 wxRect& flBounds = mpDraggedBar->mDimInfo.mBounds[wxCBAR_FLOATING];
351
352 if ( flBounds.width != -1 )
353 {
354 newWidth = flBounds.width;
355 newHeight = flBounds.height;
356 }
357
358 mHintRect.width = newWidth;
359 mHintRect.height = newHeight;
360
361 wxRect& bounds = pPane->mBoundsInParent;
362
363 // TRUE, if hint leaves the pane through it's lower edge
364
365 bool fromLowerEdge = ( pPane->IsHorizontal() )
366 ? mousePos.y > bounds.y
367 : mousePos.x > bounds.x;
368
369 // NOTE:: ...all the below min/max things - see comments about it in StickToPane(..)
370
371 if ( pPane->IsHorizontal() && fromLowerEdge )
372 {
11a68fa3 373// bool fromLowerEdge = mousePos.y > bounds.y;
8e08b761
JS
374
375 mHintRect.y = wxMax( bounds.y + bounds.height + 1, mousePos.y - newHeight );
376
377 check_upper_overrun( mHintRect.y, newHeight, mousePos.y );
378
379 // this is how MFC's hint behaves:
380
381 if ( mMouseInRectX > newWidth )
382
383 mHintRect.x = mousePos.x - ( newWidth / 2 );
384 }
385 else
386 if ( pPane->IsHorizontal() && !fromLowerEdge )
387 {
388 mHintRect.y = wxMin( bounds.y - newHeight - 1, mousePos.y );
389
390 // -/-
391
392 if ( mMouseInRectX > newWidth )
393
394 mHintRect.x = mousePos.x - ( newWidth / 2 );
395
396 check_lower_overrun( mHintRect.y, newHeight, mousePos.y );
397 }
398 else
399 if ( !pPane->IsHorizontal() && fromLowerEdge )
400 {
401 mHintRect.x = wxMax( bounds.x + bounds.width, mousePos.x - newWidth );
402
403 // -/-
404
405 if ( mMouseInRectY > newHeight )
406
407 mHintRect.y = mousePos.y - ( newHeight / 2 );
408
409 check_upper_overrun( mHintRect.x, newWidth, mousePos.x );
410 }
411 else
412 if ( !pPane->IsHorizontal() && !fromLowerEdge )
413 {
414 mHintRect.x = wxMin( bounds.x - newWidth - 1, mousePos.x );
415
416 // -/-
417
418 if ( mMouseInRectY > newHeight )
419
420 mHintRect.y = mousePos.y - ( newHeight / 2 );
421
422 check_lower_overrun( mHintRect.x, newWidth, mousePos.x );
423 }
424
425 mMouseInRectX = mousePos.x - mHintRect.x;
426 mMouseInRectY = mousePos.y - mHintRect.y;
427
428 mpCurPane = NULL;
429}
430
431int cbBarDragPlugin::GetBarWidthInPane( cbDockPane* pPane )
432{
433 if ( pPane == mpSrcPane )
434
435 return mBarWidthInSrcPane;
436
437 // this is how MFC's bars behave:
438
439 if ( pPane->IsHorizontal() )
440
441 return mpDraggedBar->mDimInfo.mSizes[wxCBAR_DOCKED_HORIZONTALLY].x;
442 else
443 return mpDraggedBar->mDimInfo.mSizes[wxCBAR_DOCKED_VERTICALLY ].x;
444}
445
446int cbBarDragPlugin::GetBarHeightInPane( cbDockPane* pPane )
447{
448 if ( pPane->IsHorizontal() )
449
450 return mpDraggedBar->mDimInfo.mSizes[wxCBAR_DOCKED_HORIZONTALLY].y;
451 else
452 return mpDraggedBar->mDimInfo.mSizes[wxCBAR_DOCKED_VERTICALLY ].y;
453}
454
455void cbBarDragPlugin::ShowHint( bool prevWasInClient )
456{
457 bool wasDocked = FALSE;
458
459 if ( mpDraggedBar->mState != wxCBAR_FLOATING && !mpCurPane )
460 {
461 mpLayout->SetBarState( mpDraggedBar, wxCBAR_FLOATING, TRUE );
462 }
463 else
464 if ( mpDraggedBar->mState == wxCBAR_FLOATING && mpCurPane )
465 {
466 mpLayout->SetBarState( mpDraggedBar, wxCBAR_DOCKED_HORIZONTALLY, FALSE );
467
468 wasDocked = TRUE;
469 }
470
471 if ( mpSrcPane->mProps.mRealTimeUpdatesOn == FALSE )
472 {
4cbc57f0 473 // do heavy calculations first
8e08b761
JS
474
475 wxRect actualRect = mHintRect; // will be adjusted depending on drag-settings
476
477 if ( mpSrcPane->mProps.mExactDockPredictionOn && mpCurPane )
478 {
479 bool success = mpLayout->RedockBar( mpDraggedBar, mHintRect, mpCurPane, FALSE );
480
481 wxASSERT( success ); // DBG::
482
483 actualRect = mpDraggedBar->mBounds;
484
485 mpCurPane->PaneToFrame( &actualRect );
486 }
487 else
488 CalcOnScreenDims( actualRect );
489
490 // release previous hint
491
492 if ( mPrevHintRect.x != POS_UNDEFINED )
493 {
494 // erase previous rectangle
495
496 cbDrawHintRectEvent evt( mPrevHintRect, prevWasInClient, TRUE, FALSE );
497
498 mpLayout->FirePluginEvent( evt );
499 }
500
501 // draw new hint
502
503 cbDrawHintRectEvent evt( actualRect, mpCurPane == NULL, FALSE, FALSE );
504
505 mpLayout->FirePluginEvent( evt );
506
507 mPrevHintRect = actualRect;
508 }
509 else
510 {
511 // otherwise, if real-time updates option is ON
512
513 if ( mpCurPane )
514 {
515 mpLayout->GetUpdatesManager().OnStartChanges();
516
517 if ( wasDocked )
518
519 mpDraggedBar->mUMgrData.SetDirty( TRUE );
520
521 bool success = mpLayout->RedockBar( mpDraggedBar, mHintRect, mpCurPane, FALSE );
522
523 wxASSERT( success ); // DBG ::
524
525 mpLayout->GetUpdatesManager().OnFinishChanges();
526 mpLayout->GetUpdatesManager().UpdateNow();
527 }
528 else
529 {
530 if ( mpLayout->mFloatingOn )
531 {
532 // move the top-most floated bar around as user drags the hint
533
534 mpDraggedBar->mDimInfo.mBounds[ wxCBAR_FLOATING ] = mHintRect;
535
536 mpLayout->ApplyBarProperties( mpDraggedBar );
537 }
538 }
539 }
540}
541
542/*** event handlers ***/
543
544void cbBarDragPlugin::OnMouseMove( cbMotionEvent& event )
545{
546 // calculate postion in frame's coordiantes
547
548 if ( !mBarDragStarted )
549 {
550 event.Skip(); // pass event to the next plugin
551 return;
552 }
553
554 wxPoint mousePos = event.mPos;
555
556 event.mpPane->PaneToFrame( &mousePos.x, &mousePos.y );
557
558 bool prevIsInClient = ( mpCurPane == 0 );
559
560 AdjustHintRect( mousePos );
561
562 // if the hint-rect is not "tempted" to any pane yet
563
564 if ( mpCurPane == NULL )
565 {
566 cbDockPane* pPane = HitTestPanes( mHintRect );
567
568 if ( !pPane )
569
570 // enable sticking again, if we've left the pane completely
571 mCanStick = TRUE;
572
573 if ( mCanStick && pPane &&
574 GetDistanceToPane( pPane, mousePos ) < GetBarHeightInPane( pPane ) )
575
576 StickToPane( pPane, mousePos );
577 else
578 if ( pPane && HitTestPanes( mousePos ) == pPane && 0 ) // FOR NOW:: disabled
579
580 StickToPane( pPane, mousePos );
581 }
582 else
583 {
584 // otherwise, when rect is now sticked to some of the panes
585 // check if it should still remain in this pane
586
587 mCanStick = TRUE;
588
589 bool mouseInOther = IsInOtherPane( mousePos );
590
591 if ( mouseInOther )
592 {
593 cbDockPane* pPane = HitTestPanes( mousePos );
594
595 StickToPane( pPane, mousePos );
596 }
597 else
598 {
599 if ( IsInClientArea( mousePos ) )
600 {
601 cbDockPane* pPane = HitTestPanes( mHintRect );
602
603 if ( pPane &&
604 pPane != mpCurPane &&
605 GetDistanceToPane( pPane, mousePos ) < GetBarHeightInPane( pPane ) )
606
607 StickToPane( pPane, mousePos );
608 else
609 if ( !pPane )
610 {
611 UnstickFromPane( mpCurPane, mousePos );
612
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
617 }
618 else
619 if ( GetDistanceToPane( pPane, mousePos ) > GetBarHeightInPane( pPane ) )
620 {
621 if ( !HitsPane( mpCurPane, mHintRect ) )
622 {
623 UnstickFromPane( mpCurPane, mousePos );
624
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
629 }
630 }
631
632 }
633 else
634 {
635 }
636 }
637 }
638
639 ShowHint( prevIsInClient );
640
641 wxCursor* pPrevCurs = mpCurCursor;
642
643 if ( mpCurPane )
644
645 mpCurCursor = mpLayout->mpDragCursor;
646 else
647 {
648 if ( mpLayout->mFloatingOn && mpSrcPane->mProps.mRealTimeUpdatesOn )
649
650 mpCurCursor = mpLayout->mpDragCursor;
651 else
652 mpCurCursor = mpLayout->mpNECursor;
653 }
8e08b761 654 if ( pPrevCurs != mpCurCursor )
8e08b761
JS
655 mpLayout->GetParentFrame().SetCursor( *mpCurCursor );
656}
657
658void cbBarDragPlugin::OnLButtonDown( cbLeftDownEvent& event )
659{
660 if ( mBarDragStarted )
661 {
662 wxMessageBox("DblClick!");
663 }
664
665 event.Skip();
666}
667
668void cbBarDragPlugin::OnLButtonUp( cbLeftUpEvent& event )
669{
670 if ( mBarDragStarted )
671 {
672 if ( mpSrcPane->mProps.mRealTimeUpdatesOn == FALSE )
673 {
674 // erase current rectangle, and finsih on-screen drawing session
675
676 cbDrawHintRectEvent evt( mPrevHintRect, mpCurPane == NULL, TRUE, TRUE );
677
678 mpLayout->FirePluginEvent( evt );
679
680 if ( mpCurPane != NULL )
681 {
682 if ( mpSrcPane->mProps.mExactDockPredictionOn )
683 {
684 mpLayout->RedockBar( mpDraggedBar, mHintRect, mpCurPane, FALSE );
685
686 mpLayout->GetUpdatesManager().OnFinishChanges();
687 mpLayout->GetUpdatesManager().UpdateNow();
688 }
689 else
690 mpLayout->RedockBar( mpDraggedBar, mHintRect, mpCurPane );
691 }
692 }
693
694 mHintRect.width = -1;
695
a570d5b3
JS
696 // In Windows, at least, the frame needs to have a null cursor
697 // else child windows (such as text windows) inherit the cursor
698#if 1
699 mpLayout->GetParentFrame().SetCursor( wxNullCursor );
700#else
701 mpLayout->GetParentFrame().SetCursor( *mpLayout->mpNormalCursor );
702#endif
8e08b761
JS
703
704 mpLayout->ReleaseEventsFromPane( event.mpPane );
705 mpLayout->ReleaseEventsFromPlugin( this );
706
707 mBarDragStarted = FALSE;
708
709 if ( mBarWasFloating && mpDraggedBar->mState != wxCBAR_FLOATING )
710 {
711 // save bar's floating position before it was docked
712
713 mpDraggedBar->mDimInfo.mBounds[ wxCBAR_FLOATING ] = mFloatedBarBounds;
714 }
715 }
716 else
717 event.Skip(); // pass event to the next plugin
718}
719
720void cbBarDragPlugin::OnLDblClick( cbLeftDClickEvent& event )
721{
722 int avoidCompilerWarning = 1;
723 if ( avoidCompilerWarning )
724 {
725 cbBarInfo* pHittedBar;
726 cbRowInfo* pRow;
727
728 if ( event.mpPane->HitTestPaneItems( event.mPos, // in pane's coordiantes
729 &pRow,
730 &pHittedBar ) == CB_BAR_CONTENT_HITTED
731 )
732 {
733 mpLayout->SetBarState( pHittedBar, wxCBAR_FLOATING, TRUE );
734
735 mpLayout->RepositionFloatedBar( pHittedBar );
736
737 return; // event is "eaten" by this plugin
738 }
739
740 mBarDragStarted = FALSE;
741
742 event.Skip();
743 }
744
745 //wxMessageBox("Hi, dblclick arrived!");
746}
747
748void cbBarDragPlugin::OnStartBarDragging( cbStartBarDraggingEvent& event )
749{
750 mpDraggedBar = event.mpBar;
751 mpSrcPane = event.mpPane;
752
753 mpLayout->CaptureEventsForPane( event.mpPane );
754 mpLayout->CaptureEventsForPlugin( this );
755
756 mpLayout->GetParentFrame().SetCursor( *mpLayout->mpDragCursor );
757
758 mBarDragStarted = TRUE;
759
760 wxRect inParent = mpDraggedBar->mBounds;
761
762 mBarWasFloating = mpDraggedBar->mState == wxCBAR_FLOATING;
763
764 if ( mBarWasFloating )
765 {
766 inParent = mpDraggedBar->mDimInfo.mBounds[ wxCBAR_FLOATING ];
767 mFloatedBarBounds = inParent;
768 }
769 else
770 event.mpPane->PaneToFrame( &inParent );
771
772 mHintRect.x = POS_UNDEFINED;
773
774 mHintRect.width = inParent.width;
775 mHintRect.height = inParent.height;
776
777 mMouseInRectX = event.mPos.x - inParent.x;
778 mMouseInRectY = event.mPos.y - inParent.y;
779
780 mpSrcPane = event.mpPane;
781
782 if ( mpDraggedBar->mState == wxCBAR_FLOATING )
783
784 mpCurPane = NULL;
785 else
786 mpCurPane = event.mpPane;
787
788 mPrevHintRect.x = POS_UNDEFINED;
789
790 mCanStick = FALSE; // we're not stuck into any pane now -
791 // there's nowhere to "stick-twice"
792
793 mBarWidthInSrcPane = mpDraggedBar->mDimInfo.mSizes[ mpDraggedBar->mState ].x;
794
795 if ( mpSrcPane->mProps.mRealTimeUpdatesOn == FALSE &&
796 mpSrcPane->mProps.mExactDockPredictionOn )
797
798 mpLayout->GetUpdatesManager().OnStartChanges(); // capture initial state of layout
799
800 // simulate the first mouse movement
801
802 int x = event.mPos.x, y = event.mPos.y;
803
804 mpSrcPane->FrameToPane( &x, &y );
805
806 cbMotionEvent motionEvt( wxPoint(x,y), event.mpPane );
807
808
809 this->OnMouseMove( motionEvt );
810
811 return; // event is "eaten" by this plugin
812}
813
814/*** on-screen hint-tracking related methods ***/
815
816void cbBarDragPlugin::OnDrawHintRect( cbDrawHintRectEvent& event )
817{
818 if ( !mpScrDc ) StartTracking();
819
820 DoDrawHintRect( event.mRect, event.mIsInClient );
821
822 if ( event.mLastTime )
823
824 FinishTracking();
825}
826
827#define _IMG_A 0xAA // Note: modified from _A to _IMG_A, _A was already defined (cygwin)
828#define _IMG_B 0x00 // Note: modified from _B to _IMG_A, _B was already defined (cygwin)
829#define _IMG_C 0x55 // Note: modified from _C to _IMG_C, for consistency reasons.
830#define _IMG_D 0x00 // Note: modified from _D to _IMG_D, for consistency reasons.
831
832// FOR NOW:: static
833
834static const unsigned char _gCheckerImg[16] = { _IMG_A,_IMG_B,_IMG_C,_IMG_D,
835 _IMG_A,_IMG_B,_IMG_C,_IMG_D,
836 _IMG_A,_IMG_B,_IMG_C,_IMG_D,
837 _IMG_A,_IMG_B,_IMG_C,_IMG_D
838 };
839
840void cbBarDragPlugin::StartTracking()
841{
842 mpScrDc = new wxScreenDC;
843
844 wxScreenDC::StartDrawingOnTop(&mpLayout->GetParentFrame());
845}
846
847void cbBarDragPlugin::DoDrawHintRect( wxRect& rect, bool isInClientRect)
848{
849 wxRect scrRect;
850
851 RectToScr( rect, scrRect );
852
853 int prevLF = mpScrDc->GetLogicalFunction();
854
855 mpScrDc->SetLogicalFunction( wxINVERT );
856
857 if ( isInClientRect )
858 {
859 // BUG BUG BUG (wx):: somehow stippled brush works only
860 // when the bitmap created on stack, not
861 // as a member of the class
862
863 wxBitmap checker( (const char*)_gCheckerImg, 8,8 );
864
865 wxBrush checkerBrush( checker );
866
867 mpScrDc->SetPen( mpLayout->mNullPen );
868 mpScrDc->SetBrush( checkerBrush );
869
870 int half = mInClientHintBorder / 2;
871
872 mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y - half,
873 scrRect.width + 2*half, mInClientHintBorder );
874
875 mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y + scrRect.height - half,
876 scrRect.width + 2*half, mInClientHintBorder );
877
878 mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y + half - 1,
879 mInClientHintBorder, scrRect.height - 2*half + 2);
880
881 mpScrDc->DrawRectangle( scrRect.x + scrRect.width - half,
882 scrRect.y + half - 1,
883 mInClientHintBorder, scrRect.height - 2*half + 2);
884
885 mpScrDc->SetBrush( wxNullBrush );
886 }
887 else
888 {
889 mpScrDc->SetPen( mpLayout->mBlackPen );
890
891 mpScrDc->DrawLine( scrRect.x, scrRect.y,
892 scrRect.x + scrRect.width, scrRect.y );
893
894 mpScrDc->DrawLine( scrRect.x, scrRect.y + 1,
895 scrRect.x, scrRect.y + scrRect.height );
896
897 mpScrDc->DrawLine( scrRect.x+1, scrRect.y + scrRect.height,
898 scrRect.x + scrRect.width, scrRect.y + scrRect.height );
899
900 mpScrDc->DrawLine( scrRect.x + scrRect.width , scrRect.y,
901 scrRect.x + scrRect.width, scrRect.y + scrRect.height + 1);
902 }
903
904 mpScrDc->SetLogicalFunction( prevLF );
905}
906
907void cbBarDragPlugin::DrawHintRect ( wxRect& rect, bool isInClientRect)
908{
909 DoDrawHintRect( rect, isInClientRect );
910}
911
912void cbBarDragPlugin::EraseHintRect( wxRect& rect, bool isInClientRect)
913{
914 DoDrawHintRect( rect, isInClientRect );
915}
916
917void cbBarDragPlugin::FinishTracking()
918{
919 wxScreenDC::EndDrawingOnTop();
920
921 delete mpScrDc;
922
923 mpScrDc = NULL;
924}
925
926void cbBarDragPlugin::RectToScr( wxRect& frameRect, wxRect& scrRect )
927{
928 scrRect = frameRect;
929
930 int x = frameRect.x, y = frameRect.y;
931
932 mpLayout->GetParentFrame().ClientToScreen( &x, &y );
933
934 scrRect.x = x;
935 scrRect.y = y;
936}
937