1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Contrib. demo
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleksandras Gluchovas
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "panedrawpl.h"
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
31 #include "wx/utils.h" // import wxMin,wxMax macros
33 #include "panedrawpl.h"
35 // bitmap bits used by bar-resizing brush
42 static const unsigned char _gCheckerImg
[16] = { _A
,_B
,_C
,_D
,
48 static void set_cursor_bits( const char** img
, char* bits
, int width
, int height
)
50 for( int i
= 0; i
!= (width
*height
)/8; ++i
)
53 for( int y
= 0; y
!= height
; ++y
)
55 const char* row
= img
[0];
57 for( int x
= 0; x
!= width
; ++x
)
59 int bitNo
= y
*width
+ x
;
61 char value
= ( row
[x
] != '.' ) ? 1 : 0;
63 bits
[ bitNo
/ sizeof(char) ] |=
64 ( ( bitNo %sizeof
(char) ) << value
);
71 /***** Implementation for class cbPaneDrawPlugin *****/
73 IMPLEMENT_DYNAMIC_CLASS( cbPaneDrawPlugin
, cbPluginBase
)
75 BEGIN_EVENT_TABLE( cbPaneDrawPlugin
, cbPluginBase
)
77 EVT_PL_LEFT_DOWN ( cbPaneDrawPlugin::OnLButtonDown
)
78 EVT_PL_LEFT_UP ( cbPaneDrawPlugin::OnLButtonUp
)
79 // EVT_PL_LEFT_DCLICK ( cbPaneDrawPlugin::OnLDblClick )
80 EVT_PL_RIGHT_UP ( cbPaneDrawPlugin::OnRButtonUp
)
81 EVT_PL_MOTION ( cbPaneDrawPlugin::OnMouseMove
)
84 EVT_PL_DRAW_PANE_BKGROUND ( cbPaneDrawPlugin::OnDrawPaneBackground
)
85 EVT_PL_DRAW_PANE_DECOR ( cbPaneDrawPlugin::OnDrawPaneDecorations
)
87 EVT_PL_DRAW_ROW_DECOR ( cbPaneDrawPlugin::OnDrawRowDecorations
)
88 EVT_PL_DRAW_ROW_HANDLES ( cbPaneDrawPlugin::OnDrawRowHandles
)
89 EVT_PL_DRAW_ROW_BKGROUND ( cbPaneDrawPlugin::OnDrawRowBackground
)
91 EVT_PL_SIZE_BAR_WND ( cbPaneDrawPlugin::OnSizeBarWindow
)
92 EVT_PL_DRAW_BAR_DECOR ( cbPaneDrawPlugin::OnDrawBarDecorations
)
93 EVT_PL_DRAW_BAR_HANDLES ( cbPaneDrawPlugin::OnDrawBarHandles
)
95 EVT_PL_START_DRAW_IN_AREA ( cbPaneDrawPlugin::OnStartDrawInArea
)
96 EVT_PL_FINISH_DRAW_IN_AREA ( cbPaneDrawPlugin::OnFinishDrawInArea
)
100 cbPaneDrawPlugin::cbPaneDrawPlugin(void)
102 : mResizeStarted ( FALSE
),
104 mResizeCursorOn ( FALSE
),
105 mpDraggedBar ( NULL
),
106 mpResizedRow ( NULL
),
112 cbPaneDrawPlugin::cbPaneDrawPlugin( wxFrameLayout
* pPanel
, int paneMask
)
114 : cbPluginBase( pPanel
, paneMask
),
116 // bar-row resizing state varaibles
118 mResizeStarted ( FALSE
),
120 mResizeCursorOn ( FALSE
),
121 mpDraggedBar ( NULL
),
122 mpResizedRow ( NULL
),
124 mRowHandleHitted ( FALSE
),
125 mIsUpperHandle ( FALSE
),
126 mBarHandleHitted ( FALSE
),
127 mIsLeftHandle ( FALSE
),
128 mBarContentHitted ( FALSE
),
134 cbPaneDrawPlugin::~cbPaneDrawPlugin()
137 wxASSERT( mpClntDc
== NULL
);
140 void cbPaneDrawPlugin::DrawDraggedHandle( const wxPoint
& pos
, cbDockPane
& pane
)
147 pane
.PaneToFrame( &fpos
.x
, &fpos
.y
);
150 int resizeHndSize
= pane
.mProps
.mResizeHandleSize
;
152 // "Required for X to specify that
153 // that we wish to draw on top of all windows
154 // - and we optimise by specifying the area
155 // for creating the overlap window." --J.S.
157 wxScreenDC::StartDrawingOnTop(&mpLayout
->GetParentFrame());
159 mpLayout
->GetParentFrame().ClientToScreen( &ofsX
, &ofsY
);
161 int prevLF
= dc
.GetLogicalFunction();
163 // BUG BUG BUG (wx):: somehow stippled brush works only
164 // when the bitmap created on stack, not
165 // as a member of the class
167 wxBitmap
checker( (const char*)_gCheckerImg
, 8,8 );
169 wxBrush
checkerBrush( checker
);
171 dc
.SetPen( mpLayout
->mNullPen
);
172 dc
.SetBrush( checkerBrush
);
173 dc
.SetLogicalFunction( wxXOR
);
175 if ( mHandleIsVertical
)
177 int delta
= pos
.x
- mDragOrigin
.x
;
179 if ( !pane
.IsHorizontal() )
181 delta
= pos
.y
- mDragOrigin
.y
;
184 realHndOfs
= pane
.mBoundsInParent
.x
+ pane
.mLeftMargin
+ mHandleOfs
;
186 int newX
= realHndOfs
+ delta
;
188 if ( newX
+ resizeHndSize
> mHandleDragArea
.x
+ mHandleDragArea
.width
)
190 newX
= mHandleDragArea
.x
+ mHandleDragArea
.width
- 1;
192 if ( newX
< mHandleDragArea
.x
)
194 newX
= mHandleDragArea
.x
;
196 mDraggedDelta
= newX
- realHndOfs
;
198 dc
.DrawRectangle( newX
+ ofsX
, mHandleDragArea
.y
+ ofsY
,
200 mHandleDragArea
.height
+1 );
204 // otherwise, draw horizontal handle
206 int delta
= pos
.y
- mDragOrigin
.y
;
208 if ( !pane
.IsHorizontal() )
210 delta
= pos
.x
- mDragOrigin
.x
;
213 realHndOfs
= pane
.mBoundsInParent
.y
+ pane
.mTopMargin
+ mHandleOfs
;
215 int newY
= realHndOfs
+ delta
;
217 if ( newY
+ resizeHndSize
> mHandleDragArea
.y
+ mHandleDragArea
.height
)
219 newY
= mHandleDragArea
.y
+ mHandleDragArea
.height
- 1;
221 if ( newY
< mHandleDragArea
.y
)
223 newY
= mHandleDragArea
.y
;
225 mDraggedDelta
= newY
- realHndOfs
;
227 dc
.DrawRectangle( mHandleDragArea
.x
+ ofsX
, newY
+ ofsY
,
228 mHandleDragArea
.width
+ 1,
232 dc
.SetLogicalFunction( prevLF
);
234 // "End drawing on top (frees the window used for drawing
235 // over the screen)" --J.S.
236 wxScreenDC::EndDrawingOnTop();
239 void cbPaneDrawPlugin::OnMouseMove( cbMotionEvent
& event
)
241 if ( !mResizeStarted
)
243 // if nothing is started, do hit-tests
245 bool prevWasRowHandle
= mRowHandleHitted
;
247 mBarContentHitted
= FALSE
;
248 mBarHandleHitted
= FALSE
;
249 mRowHandleHitted
= FALSE
;
252 event
.mpPane
->HitTestPaneItems( event
.mPos
, // in pane's coordiantes
256 if ( testResult
!= CB_NO_ITEMS_HITTED
)
258 if ( testResult
== CB_BAR_CONTENT_HITTED
)
260 // restore cursor, if non of the handles were hit
261 if ( mResizeCursorOn
)
263 // remove resizing hints
265 mpLayout
->ReleaseEventsFromPane( event
.mpPane
);
266 mpLayout
->ReleaseEventsFromPlugin( this );
268 mResizeCursorOn
= FALSE
;
270 mBarContentHitted
= TRUE
;
272 mpLayout
->GetParentFrame().SetCursor( *mpLayout
->mpNormalCursor
);
275 // TBD:: fire something like "mouse-over-bar" event
277 event
.Skip(); // pass event to the next handler in the chain
281 wxCursor
* pCurs
= NULL
;
283 if ( testResult
== CB_UPPER_ROW_HANDLE_HITTED
||
284 testResult
== CB_LOWER_ROW_HANDLE_HITTED
)
286 if ( event
.mpPane
->IsHorizontal() )
288 pCurs
= mpLayout
->mpVertCursor
;
290 pCurs
= mpLayout
->mpHorizCursor
;
292 mRowHandleHitted
= TRUE
;
293 mIsUpperHandle
= ( testResult
== CB_UPPER_ROW_HANDLE_HITTED
);
297 // otherwise, if inter-bar handle was hitted
299 if ( event
.mpPane
->IsHorizontal() )
301 pCurs
= mpLayout
->mpHorizCursor
;
303 pCurs
= mpLayout
->mpVertCursor
;
305 mBarHandleHitted
= TRUE
;
306 mIsLeftHandle
= ( testResult
== CB_LEFT_BAR_HANDLE_HITTED
);
309 // avoid setting the same cursor twice
311 if ( !mResizeCursorOn
|| prevWasRowHandle
!= mRowHandleHitted
)
313 if ( !mResizeCursorOn
)
315 // caputre if not captured yet
316 mpLayout
->CaptureEventsForPane( event
.mpPane
);
317 mpLayout
->CaptureEventsForPlugin( this );
320 mpLayout
->GetParentFrame().SetCursor( *pCurs
);
323 mResizeCursorOn
= TRUE
;
325 // handled is being dragged now, thus event is "eaten" by this plugin
329 } // end of if (HitTestBarHandles())
331 // restore cursor, if non of the handles were hit
332 if ( mResizeCursorOn
)
334 mpLayout
->ReleaseEventsFromPane( event
.mpPane
);
335 mpLayout
->ReleaseEventsFromPlugin( this );
337 mpLayout
->GetParentFrame().SetCursor( *mpLayout
->mpNormalCursor
);
339 mResizeCursorOn
= FALSE
;
342 event
.Skip(); // pass event to the next plugin
345 // othewise series of actions, if something has already started
348 if ( mResizeStarted
)
350 // apply xor-mask twice
351 DrawDraggedHandle( mPrevPos
, *event
.mpPane
);
353 // draw handle in the new position
354 DrawDraggedHandle( event
.mPos
, *event
.mpPane
);
355 mPrevPos
= event
.mPos
;
357 // handled is dragged, thus event is "eaten" by this plugin
360 event
.Skip(); // pass event to the next plugin
363 void cbPaneDrawPlugin::OnLDblClick( cbLeftDClickEvent
& event
)
365 if ( !mResizeCursorOn
)
367 cbBarInfo
* pBarToFloat
;
369 if ( event
.mpPane
->HitTestPaneItems( event
.mPos
, // in pane's coordiantes
371 &pBarToFloat
) == CB_BAR_CONTENT_HITTED
376 mpLayout
->SetBarState( pBarToFloat
, wxCBAR_FLOATING
, TRUE
);
378 mpLayout
->RepositionFloatedBar( pBarToFloat
);
380 return; // event is "eaten" by this plugin
387 void cbPaneDrawPlugin::OnLButtonDown( cbLeftDownEvent
& event
)
389 wxASSERT( !mResizeStarted
);
391 if ( mResizeCursorOn
)
393 mResizeStarted
= TRUE
;
394 mDragOrigin
= event
.mPos
;
396 cbBarInfo
* pInfo
= NULL
;
398 // setup constraints for the dragging handle
402 mHandleIsVertical
= FALSE
;
404 if ( mRowHandleHitted
)
406 event
.mpPane
->GetRowResizeRange( mpResizedRow
, &from
, &till
, mIsUpperHandle
);
408 // otherwise if bar handle was hitted
409 event
.mpPane
->GetBarResizeRange( mpDraggedBar
, &from
, &till
, mIsLeftHandle
);
411 if ( mRowHandleHitted
)
413 mHandleIsVertical
= ( event
.mpPane
->IsHorizontal() ) ? FALSE
: TRUE
;
415 mHandleDragArea
.x
= 0;
416 mHandleDragArea
.width
= event
.mpPane
->mPaneWidth
;
418 mHandleDragArea
.y
= from
;
419 mHandleDragArea
.height
= till
- from
;
421 if ( mIsUpperHandle
)
423 mHandleOfs
= mpResizedRow
->mRowY
;
425 mHandleOfs
= mpResizedRow
->mRowY
+
426 mpResizedRow
->mRowHeight
-
427 event
.mpPane
->mProps
.mResizeHandleSize
;
431 // otehrwise if bar handle dragged
433 cbRowInfo
& rowInfo
= *mpDraggedBar
->mpRow
;
434 wxRect
& bounds
= mpDraggedBar
->mBounds
;
436 mHandleIsVertical
= ( event
.mpPane
->IsHorizontal() ) ? TRUE
: FALSE
;
438 mHandleDragArea
.x
= from
;
439 mHandleDragArea
.width
= till
- from
;
442 mHandleDragArea
.y
= bounds
.y
;
443 mHandleDragArea
.height
= bounds
.height
;
445 // left-side-handle mBounds
448 mHandleOfs
= bounds
.x
;
450 mHandleOfs
= bounds
.x
+
451 bounds
.width
- event
.mpPane
->mProps
.mResizeHandleSize
;
455 event
.mpPane
->PaneToFrame( &mHandleDragArea
);
456 DrawDraggedHandle(mDragOrigin
, *event
.mpPane
);
458 mPrevPos
= mDragOrigin
;
461 // handled is dragged, thus event is "eaten" by this plugin
465 cbBarInfo
* pDraggedBar
;
467 if ( event
.mpPane
->HitTestPaneItems( event
.mPos
, // in pane's coordiantes
469 &pDraggedBar
) == CB_BAR_CONTENT_HITTED
472 long x
= event
.mPos
.x
,
475 event
.mpPane
->PaneToFrame( &x
, &y
);
477 cbStartBarDraggingEvent
dragEvt( pDraggedBar
, wxPoint(x
,y
), event
.mpPane
);
479 mpLayout
->FirePluginEvent( dragEvt
);
481 return; // event is "eaten" by this plugin
485 event
.Skip(); // pass event to the next plugin in the chain
488 void cbPaneDrawPlugin::OnLButtonUp( cbLeftUpEvent
& event
)
490 if ( mResizeStarted
)
492 DrawDraggedHandle( event
.mPos
, *event
.mpPane
);
494 mResizeStarted
= FALSE
;
495 mResizeCursorOn
= FALSE
;
497 mpLayout
->ReleaseEventsFromPane( event
.mpPane
);
498 mpLayout
->ReleaseEventsFromPlugin( this );
500 mpLayout
->GetParentFrame().SetCursor( *mpLayout
->mpNormalCursor
);
502 if ( mRowHandleHitted
)
504 event
.mpPane
->ResizeRow( mpResizedRow
,
510 event
.mpPane
->ResizeBar( mpDraggedBar
,
518 // handled dragging action was finished by this mouse-up,
519 // thus event is "eaten" by this plugin
524 event
.Skip(); // pass event to the next plugin
527 void cbPaneDrawPlugin::OnRButtonUp( cbRightUpEvent
& event
)
529 wxPoint fpos
= event
.mPos
;
530 event
.mpPane
->PaneToFrame( &fpos
.x
, &fpos
.y
);
532 cbBarInfo
* pDraggedBar
;
534 // user clicks inside the bar contnet, fire bar-customization event
536 if ( event
.mpPane
->HitTestPaneItems( event
.mPos
, // in pane's coordiantes
538 &pDraggedBar
) == CB_BAR_CONTENT_HITTED
541 cbCustomizeBarEvent
cbEvt( pDraggedBar
, fpos
, event
.mpPane
);
543 mpLayout
->FirePluginEvent( cbEvt
);
545 return; // event is "eaten" by this plugin
548 // otherwise fire whole-layout customization event
550 cbCustomizeLayoutEvent
csEvt( fpos
);
552 mpLayout
->FirePluginEvent( csEvt
);
554 // event is "eaten" by this plugin
557 void cbPaneDrawPlugin::OnSizeBarWindow( cbSizeBarWndEvent
& event
)
559 cbBarInfo
& bar
= *event
.mpBar
;
560 mpPane
= event
.mpPane
;
562 // it's possible that a bar does not have it's own window!
563 if ( !bar
.mpBarWnd
) return;
565 wxRect
& bounds
= event
.mBoundsInParent
;
568 if ( bounds
.height
!= 0 )
570 // size smaller than bounds, to leave space for shade lines
574 bar
.mpBarWnd
->wxWindow::SetSize( bounds
.x
+ 1 + bar
.mDimInfo
.mHorizGap
,
575 bounds
.y
+ 1 + bar
.mDimInfo
.mVertGap
,
576 bounds
.width
- 2 - bar
.mDimInfo
.mHorizGap
*2,
577 bounds
.height
- 2 - bar
.mDimInfo
.mVertGap
*2 ,
581 if ( !bar
.mpBarWnd
->IsShown() )
583 bar
.mpBarWnd
->Show( TRUE
);
586 // hide bar if not visable
587 bar
.mpBarWnd
->Show( FALSE
);
589 event
.Skip(); // pass event to the next plugin in the chain
592 void cbPaneDrawPlugin::OnDrawRowDecorations( cbDrawRowDecorEvent
& event
)
594 DrawPaneShadeForRow( event
.mpRow
, *event
.mpDc
);
596 event
.Skip(); // pass event to the next plugin
599 void cbPaneDrawPlugin::DrawUpperRowHandle( cbRowInfo
* pRow
, wxDC
& dc
)
601 wxRect
& bounds
= pRow
->mBoundsInParent
;
603 if ( mpPane
->IsHorizontal() )
605 if ( pRow
->mHasUpperHandle
)
607 mpPane
->DrawHorizHandle( dc
, bounds
.x
,
613 if ( pRow
->mHasUpperHandle
)
615 mpPane
->DrawVertHandle( dc
, bounds
.x
-1,
616 bounds
.y
, pRow
->mRowWidth
);
620 void cbPaneDrawPlugin::DrawLowerRowHandle( cbRowInfo
* pRow
, wxDC
& dc
)
622 wxRect
& bounds
= pRow
->mBoundsInParent
;
624 // check if iter-row handles present
626 if ( mpPane
->IsHorizontal() )
628 if ( pRow
->mHasLowerHandle
)
630 mpPane
->DrawHorizHandle( dc
, bounds
.x
, bounds
.y
+ bounds
.height
- mpPane
->mProps
.mResizeHandleSize
- 1,
635 if ( pRow
->mHasLowerHandle
)
637 mpPane
->DrawVertHandle( dc
, bounds
.x
+ bounds
.width
- mpPane
->mProps
.mResizeHandleSize
- 1,
638 bounds
.y
, pRow
->mRowWidth
);
642 void cbPaneDrawPlugin::OnDrawRowHandles( cbDrawRowHandlesEvent
& event
)
645 cbRowInfo
* pRow
= event
.mpRow
;
646 wxDC
& dc
= *event
.mpDc
;
647 mpPane
= event
.mpPane
;
649 // draw handles of surrounding rows first
651 if ( pRow
->mpPrev
&& pRow
->mpPrev
->mHasLowerHandle
)
653 DrawLowerRowHandle( pRow
->mpPrev
, dc
);
655 if ( pRow
->mpNext
&& pRow
->mpNext
->mHasUpperHandle
)
657 DrawUpperRowHandle( pRow
->mpNext
, dc
);
659 // draw handles of the given row
661 if ( pRow
->mHasUpperHandle
)
663 DrawUpperRowHandle( pRow
, dc
);
665 if ( pRow
->mHasLowerHandle
)
667 DrawLowerRowHandle( pRow
, dc
);
669 event
.Skip(); // pass event to the next plugin
672 void cbPaneDrawPlugin::OnDrawPaneBackground ( cbDrawPaneBkGroundEvent
& event
)
674 wxDC
& dc
= *event
.mpDc
;
675 mpPane
= event
.mpPane
;
677 // FOR NOW:: hard-coded
678 wxBrush
bkBrush( mpLayout
->mBorderPen
.GetColour(), wxSOLID
);
680 dc
.SetBrush( bkBrush
);
681 dc
.SetPen( mpLayout
->mNullPen
);
683 wxRect
& bounds
= mpPane
->mBoundsInParent
;
685 if ( mpPane
->mTopMargin
>= 1 )
687 dc
.DrawRectangle( bounds
.x
, bounds
.y
,
689 mpPane
->mTopMargin
+ 1);
692 if ( mpPane
->mBottomMargin
>= 1 )
694 dc
.DrawRectangle( bounds
.x
,
695 bounds
.y
+ bounds
.height
- mpPane
->mBottomMargin
,
697 mpPane
->mBottomMargin
+ 1);
700 if ( mpPane
->mLeftMargin
>= 1 )
702 dc
.DrawRectangle( bounds
.x
,
703 bounds
.y
+ mpPane
->mTopMargin
- 1,
704 mpPane
->mLeftMargin
+ 1,
705 bounds
.height
- mpPane
->mTopMargin
- mpPane
->mBottomMargin
+ 2);
708 if ( mpPane
->mRightMargin
>= 1 )
710 dc
.DrawRectangle( bounds
.x
+ bounds
.width
- mpPane
->mRightMargin
,
711 bounds
.y
+ mpPane
->mTopMargin
- 1,
712 mpPane
->mRightMargin
+ 1,
713 bounds
.height
- mpPane
->mTopMargin
- mpPane
->mBottomMargin
+ 2);
715 event
.Skip(); // pass event to the next plugin
718 void cbPaneDrawPlugin::OnDrawRowBackground ( cbDrawRowBkGroundEvent
& event
)
721 cbRowInfo
* pRow
= event
.mpRow
;
722 wxDC
& dc
= *event
.mpDc
;
723 mpPane
= event
.mpPane
;
726 wxRect rowBounds
= pRow
->mBoundsInParent
;
727 bool isHorizontal
= event
.mpPane
->IsHorizontal();
733 prevPos
= rowBounds
.x
;
734 // include one line obove and below the row
736 rowBounds
.height
+=2;
739 rowBounds
.width
+= 2;
743 prevPos
= rowBounds
.y
;
744 // include one line obove and below the row
746 rowBounds
.width
+= 2;
749 rowBounds
.height
+=2;
752 //#define TEST_BK_ERASING
754 #ifdef TEST_BK_ERASING
757 wxBrush
br0( wxColour(0,160,160), wxSOLID
);
759 dc
.SetPen ( mpLayout
->mNullPen
);
760 dc
.DrawRectangle( rowBounds
.x
, rowBounds
.y
,
762 rowBounds
.height
+ 1 );
765 wxBrush
bkBrush( mpLayout
->mGrayPen
.GetColour(), wxSOLID
);
767 dc
.SetPen ( mpLayout
->mNullPen
);
768 dc
.SetBrush( bkBrush
);
770 // fill background-recatangle of entire row area
771 dc
.DrawRectangle( rowBounds
.x
, rowBounds
.y
,
773 rowBounds
.height
+ 1 );
775 dc
.SetBrush( wxNullBrush
);
777 // draw "shaded-side-bars" for each bar
778 for( size_t i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
780 wxRect
& bounds
= pRow
->mBars
[i
]->mBoundsInParent
;
784 DrawShade( 1, bounds
, wxLEFT
, dc
);
785 DrawShade( 1, bounds
, wxRIGHT
, dc
);
789 DrawShade( 1, bounds
, wxTOP
, dc
);
790 DrawShade( 1, bounds
, wxBOTTOM
, dc
);
794 // draw extra shades to simulate "glued-bricks" effect
796 // TBD:: reduce exessive drawing of shades, when the
797 // row handle is present, and shades will be overr-drawn anyway
799 DrawUpperRowShades( pRow
, dc
, 1 ); // outer shade
803 DrawLowerRowShades( pRow
->mpPrev
, dc
, 1 ); // outter shade
804 DrawLowerRowShades( pRow
->mpPrev
, dc
, 0 ); // inner shade
807 DrawLowerRowShades( pRow
, dc
, 1 );
811 DrawUpperRowShades( pRow
->mpNext
, dc
, 1 );
812 DrawUpperRowShades( pRow
->mpNext
, dc
, 0 );
815 event
.Skip(); // pass event to the next plugin
818 void cbPaneDrawPlugin::DrawUpperRowShades( cbRowInfo
* pRow
, wxDC
& dc
, int level
)
820 for( size_t i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
822 wxRect
& bounds
= pRow
->mBars
[i
]->mBoundsInParent
;
824 if ( mpPane
->IsHorizontal() )
826 DrawShade( level
, bounds
, wxTOP
, dc
);
829 dc
.SetPen( mpLayout
->mDarkPen
);
830 dc
.DrawPoint( bounds
.x
- 1, bounds
.y
);
831 dc
.SetPen( mpLayout
->mLightPen
);
832 dc
.DrawPoint( bounds
.x
+ bounds
.width
, bounds
.y
);
837 DrawShade( level
, bounds
, wxLEFT
, dc
);
840 dc
.SetPen( mpLayout
->mDarkPen
);
841 dc
.DrawPoint( bounds
.x
, bounds
.y
-1 );
842 dc
.SetPen( mpLayout
->mLightPen
);
843 dc
.DrawPoint( bounds
.x
, bounds
.y
+ bounds
.height
);
849 void cbPaneDrawPlugin::DrawLowerRowShades( cbRowInfo
* pRow
, wxDC
& dc
, int level
)
853 for( size_t i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
855 wxRect
& bounds
= pRow
->mBars
[i
]->mBoundsInParent
;
857 if ( mpPane
->IsHorizontal() )
859 DrawShade( level
, bounds
, wxBOTTOM
, dc
);
862 dc
.SetPen( mpLayout
->mDarkPen
);
863 dc
.DrawPoint( bounds
.x
- 1, bounds
.y
+ bounds
.height
-1 );
864 dc
.SetPen( mpLayout
->mLightPen
);
865 dc
.DrawPoint( bounds
.x
+ bounds
.width
, bounds
.y
+ bounds
.height
-1 );
870 DrawShade( level
, bounds
, wxRIGHT
, dc
);
873 dc
.SetPen( mpLayout
->mDarkPen
);
874 dc
.DrawPoint( bounds
.x
+ bounds
.width
- 1, bounds
.y
-1 );
875 dc
.SetPen( mpLayout
->mLightPen
);
876 dc
.DrawPoint( bounds
.x
+ bounds
.width
- 1, bounds
.y
+ bounds
.height
);
882 void cbPaneDrawPlugin::DrawBarInnerShadeRect( cbBarInfo
* pBar
, wxDC
& dc
)
884 wxRect
& bounds
= pBar
->mBoundsInParent
;
886 dc
.SetPen( mpLayout
->mDarkPen
);
888 dc
.DrawLine( bounds
.x
+ bounds
.width
- 1,
890 bounds
.x
+ bounds
.width
- 1,
891 bounds
.y
+ bounds
.height
);
893 dc
.DrawLine( bounds
.x
,
894 bounds
.y
+ bounds
.height
- 1,
895 bounds
.x
+ bounds
.width
,
896 bounds
.y
+ bounds
.height
-1 );
898 dc
.SetPen( mpLayout
->mLightPen
);
900 dc
.DrawLine( bounds
.x
,
902 bounds
.x
+ bounds
.width
- 1,
905 dc
.DrawLine( bounds
.x
,
908 bounds
.y
+ bounds
.height
- 1 );
911 void cbPaneDrawPlugin::DrawShade( int level
, wxRect
& rect
, int alignment
, wxDC
& dc
)
913 // simulates "guled-bricks" appearence of control bars
915 if ( ( alignment
== wxTOP
&& level
== 1 ) ||
916 ( alignment
== wxBOTTOM
&& level
== 0 ) ||
917 ( alignment
== wxLEFT
&& level
== 1 ) ||
918 ( alignment
== wxRIGHT
&& level
== 0 )
921 dc
.SetPen( mpLayout
->mDarkPen
);
923 dc
.SetPen( mpLayout
->mLightPen
);
925 if ( alignment
== wxTOP
)
931 rect
.x
+ rect
.width
- 1,
934 dc
.DrawLine( rect
.x
- 1,
936 rect
.x
+ rect
.width
+ 0,
940 if ( alignment
== wxBOTTOM
)
945 rect
.y
+ rect
.height
- 1,
947 rect
.y
+ rect
.height
- 1 );
949 dc
.DrawLine( rect
.x
- 1,
950 rect
.y
+ rect
.height
,
951 rect
.x
+ rect
.width
+ 1,
952 rect
.y
+ rect
.height
);
955 if ( alignment
== wxLEFT
)
962 rect
.y
+ rect
.height
- 1 );
964 dc
.DrawLine( rect
.x
- 1,
967 rect
.y
+ rect
.height
);
970 if ( alignment
== wxRIGHT
)
974 dc
.DrawLine( rect
.x
+ rect
.width
- 1,
976 rect
.x
+ rect
.width
- 1,
977 rect
.y
+ rect
.height
);
980 dc
.DrawLine( rect
.x
+ rect
.width
,
983 rect
.y
+ rect
.height
+ 1 );
988 void cbPaneDrawPlugin::DrawShade1( int level
, wxRect
& rect
, int alignment
, wxDC
& dc
)
990 // simulates "guled-bricks" appearence of control bars
992 if ( ( alignment
== wxTOP
&& level
== 1 ) ||
993 ( alignment
== wxBOTTOM
&& level
== 0 ) ||
994 ( alignment
== wxLEFT
&& level
== 1 ) ||
995 ( alignment
== wxRIGHT
&& level
== 0 )
998 dc
.SetPen( mpLayout
->mDarkPen
);
1000 dc
.SetPen( mpLayout
->mLightPen
);
1002 if ( alignment
== wxTOP
)
1006 dc
.DrawLine( rect
.x
,
1008 rect
.x
+ rect
.width
,
1011 dc
.DrawLine( rect
.x
,
1013 rect
.x
+ rect
.width
,
1017 if ( alignment
== wxBOTTOM
)
1021 dc
.DrawLine( rect
.x
,
1022 rect
.y
+ rect
.height
- 1,
1023 rect
.x
+ rect
.width
,
1024 rect
.y
+ rect
.height
- 1 );
1026 dc
.DrawLine( rect
.x
,
1027 rect
.y
+ rect
.height
,
1028 rect
.x
+ rect
.width
,
1029 rect
.y
+ rect
.height
);
1032 if ( alignment
== wxLEFT
)
1036 dc
.DrawLine( rect
.x
,
1039 rect
.y
+ rect
.height
);
1041 dc
.DrawLine( rect
.x
- 1,
1044 rect
.y
+ rect
.height
);
1047 if ( alignment
== wxRIGHT
)
1051 dc
.DrawLine( rect
.x
+ rect
.width
- 1,
1053 rect
.x
+ rect
.width
- 1,
1054 rect
.y
+ rect
.height
);
1057 dc
.DrawLine( rect
.x
+ rect
.width
,
1059 rect
.x
+ rect
.width
,
1060 rect
.y
+ rect
.height
);
1065 void cbPaneDrawPlugin::DrawPaneShade( wxDC
& dc
, int alignment
)
1067 if ( !mpPane
->mProps
.mShow3DPaneBorderOn
) return;
1069 wxRect bounds
= mpPane
->mBoundsInParent
;
1071 bounds
.x
+= mpPane
->mLeftMargin
;
1072 bounds
.y
+= mpPane
->mTopMargin
;
1073 bounds
.width
-= ( mpPane
->mLeftMargin
+ mpPane
->mRightMargin
);
1074 bounds
.height
-= ( mpPane
->mTopMargin
+ mpPane
->mBottomMargin
);
1076 DrawShade( 0, bounds
, alignment
, dc
);
1077 DrawShade( 1, bounds
, alignment
, dc
);
1080 void cbPaneDrawPlugin::DrawPaneShadeForRow( cbRowInfo
* pRow
, wxDC
& dc
)
1082 if ( !mpPane
->mProps
.mShow3DPaneBorderOn
) return;
1084 // do not draw decoration, if pane has "vainished"
1085 if ( mpPane
->mPaneWidth
< 0 ||
1086 mpPane
->mPaneHeight
< 0 )
1090 wxRect bounds
= pRow
->mBoundsInParent
;
1092 if ( mpPane
->mAlignment
== wxTOP
||
1093 mpPane
->mAlignment
== wxBOTTOM
)
1098 DrawShade1( 0, bounds
, wxLEFT
, dc
);
1099 DrawShade1( 1, bounds
, wxLEFT
, dc
);
1100 DrawShade1( 0, bounds
, wxRIGHT
, dc
);
1101 DrawShade1( 1, bounds
, wxRIGHT
, dc
);
1103 if ( !pRow
->mpNext
)
1104 DrawPaneShade( dc
, wxBOTTOM
);
1106 if ( !pRow
->mpPrev
)
1107 DrawPaneShade( dc
, wxTOP
);
1114 DrawShade1( 0, bounds
, wxTOP
, dc
);
1115 DrawShade1( 1, bounds
, wxTOP
, dc
);
1116 DrawShade1( 0, bounds
, wxBOTTOM
, dc
);
1117 DrawShade1( 1, bounds
, wxBOTTOM
, dc
);
1119 if ( !pRow
->mpNext
)
1120 DrawPaneShade( dc
, wxRIGHT
);
1122 if ( !pRow
->mpPrev
)
1123 DrawPaneShade( dc
, wxLEFT
);
1127 void cbPaneDrawPlugin::OnDrawPaneDecorations( cbDrawPaneDecorEvent
& event
)
1129 wxDC
& dc
= *event
.mpDc
;
1131 cbDockPane
* pPane
= event
.mpPane
;
1133 RowArrayT
& lst
= pPane
->GetRowList();
1135 // FIXME:: this is a workaround for some glitches
1139 cbRowInfo
* pLastRow
= lst
[ lst
.Count() - 1 ];
1141 pPane
->PaintRowBackground( pLastRow
, dc
);
1142 pPane
->PaintRowDecorations( pLastRow
, dc
);
1143 pPane
->PaintRowHandles( pLastRow
, dc
);
1146 if ( !pPane
->mProps
.mShow3DPaneBorderOn
) return;
1148 // do not draw decoration, if pane is completely hidden
1149 if ( event
.mpPane
->mPaneWidth
< 0 ||
1150 event
.mpPane
->mPaneHeight
< 0 )
1154 DrawPaneShade( dc
, wxTOP
);
1155 DrawPaneShade( dc
, wxBOTTOM
);
1156 DrawPaneShade( dc
, wxLEFT
);
1157 DrawPaneShade( dc
, wxRIGHT
);
1159 event
.Skip(); // pass event to the next plugin
1162 // bar decoration/sizing handlers
1164 void cbPaneDrawPlugin::OnDrawBarDecorations( cbDrawBarDecorEvent
& event
)
1166 cbBarInfo
* pBar
= event
.mpBar
;
1167 wxDC
& dc
= *event
.mpDc
;
1169 // draw brick borders
1171 wxRect
& rect
= event
.mBoundsInParent
;
1173 dc
.SetPen( mpLayout
->mLightPen
);
1176 dc
.DrawLine( rect
.x
, rect
.y
,
1177 rect
.x
+ rect
.width
-1, rect
.y
);
1180 dc
.DrawLine( rect
.x
, rect
.y
,
1181 rect
.x
, rect
.y
+ rect
.height
-1 );
1184 dc
.SetPen( mpLayout
->mDarkPen
);
1187 dc
.DrawLine( rect
.x
+ rect
.width
-1, rect
.y
,
1188 rect
.x
+ rect
.width
-1, rect
.y
+ rect
.height
-1 );
1191 dc
.DrawLine( rect
.x
, rect
.y
+ rect
.height
-1,
1192 rect
.x
+ rect
.width
, rect
.y
+ rect
.height
-1 );
1194 event
.Skip(); // pass event to the next plugin
1197 void cbPaneDrawPlugin::OnDrawBarHandles( cbDrawBarHandlesEvent
& event
)
1200 cbBarInfo
* pBar
= event
.mpBar
;
1201 wxDC
& dc
= *event
.mpDc
;
1202 mpPane
= event
.mpPane
;
1204 // draw handles around the bar if present
1206 if ( pBar
->mHasLeftHandle
||
1207 pBar
->mHasRightHandle
)
1209 wxRect
& bounds
= pBar
->mBoundsInParent
;
1211 if ( mpPane
->IsHorizontal() )
1213 if ( pBar
->mHasLeftHandle
)
1215 mpPane
->DrawVertHandle( dc
, bounds
.x
- mpPane
->mProps
.mResizeHandleSize
-1,
1216 bounds
.y
, bounds
.height
);
1218 if ( pBar
->mHasRightHandle
)
1220 mpPane
->DrawVertHandle( dc
,
1221 bounds
.x
+ bounds
.width
-1,
1222 bounds
.y
, bounds
.height
);
1226 if ( pBar
->mHasLeftHandle
)
1228 mpPane
->DrawHorizHandle( dc
, bounds
.x
,
1229 bounds
.y
- mpPane
->mProps
.mResizeHandleSize
- 1,
1232 if ( pBar
->mHasRightHandle
)
1234 mpPane
->DrawHorizHandle( dc
, bounds
.x
,
1235 bounds
.y
+ bounds
.height
- 1,
1240 event
.Skip(); // pass event to the next plugin
1243 void cbPaneDrawPlugin::OnStartDrawInArea( cbStartDrawInAreaEvent
& event
)
1246 wxASSERT( mpClntDc
== NULL
);
1248 // FOR NOW:: create/destory client-dc upon each drawing
1249 mpClntDc
= new wxClientDC( &mpLayout
->GetParentFrame() );
1251 (*event
.mppDc
) = mpClntDc
;
1253 mpClntDc
->SetClippingRegion( event
.mArea
.x
, event
.mArea
.y
,
1254 event
.mArea
.width
, event
.mArea
.height
);
1257 void cbPaneDrawPlugin::OnFinishDrawInArea( cbFinishDrawInAreaEvent
& event
)
1260 wxASSERT( mpClntDc
);