Files
wxWidgets/contrib/src/fl/bardragpl.cpp
George Tasker 11a68fa3af Removed non-reachable code (consulted Aleks first, and he said the code was no longer needed)
Commented out unused variables to stop BCC warnings - left the code for debugging purposes
Removed hardcoded tabs and replaced with spaces per the wxWindows code style specs
Spelling typos fixed in comments
Miscellaneous source formatting issues fixed to meet standard wxwindows coding styles


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@12605 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2001-11-22 23:15:12 +00:00

935 lines
22 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 23/09/98
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "bardragpl.h"
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/fl/bardragpl.h"
#define POS_UNDEFINED -32768
// helpers, FOR NOW:: static
static inline bool rect_hits_rect( const wxRect& r1, const wxRect& r2 )
{
if ( ( r2.x >= r1.x && r2.x <= r1.x + r1.width ) ||
( r1.x >= r2.x && r1.x <= r2.x + r2.width ) )
if ( ( r2.y >= r1.y && r2.y <= r1.y + r1.height ) ||
( r1.y >= r2.y && r1.y <= r2.y + r2.height ) )
return TRUE;
return FALSE;
}
static inline bool rect_contains_point( const wxRect& rect, int x, int y )
{
return ( x >= rect.x &&
y >= rect.y &&
x < rect.x + rect.width &&
y < rect.y + rect.height );
}
/***** Implementation for class cbBarDragPlugin *****/
IMPLEMENT_DYNAMIC_CLASS( cbBarDragPlugin, cbPluginBase )
BEGIN_EVENT_TABLE( cbBarDragPlugin, cbPluginBase )
//EVT_PL_LEFT_DOWN ( cbBarDragPlugin::OnLButtonDown )
EVT_PL_LEFT_UP ( cbBarDragPlugin::OnLButtonUp )
EVT_PL_MOTION ( cbBarDragPlugin::OnMouseMove )
EVT_PL_DRAW_HINT_RECT ( cbBarDragPlugin::OnDrawHintRect )
EVT_PL_START_BAR_DRAGGING ( cbBarDragPlugin::OnStartBarDragging )
EVT_PL_LEFT_DCLICK ( cbBarDragPlugin::OnLDblClick )
END_EVENT_TABLE()
cbBarDragPlugin::cbBarDragPlugin(void)
: mBarDragStarted ( FALSE ),
mCanStick ( TRUE ),
mpScrDc ( NULL ),
mpCurCursor ( NULL ),
mpDraggedBar ( NULL ),
mInClientHintBorder( 4 )
{}
cbBarDragPlugin::cbBarDragPlugin( wxFrameLayout* pPanel, int paneMask )
: cbPluginBase( pPanel, paneMask ),
mBarDragStarted ( FALSE ),
mCanStick ( TRUE ),
mpScrDc ( NULL ),
mpCurCursor ( NULL ),
mpDraggedBar ( NULL ),
mInClientHintBorder( 4 )
{}
cbBarDragPlugin::~cbBarDragPlugin()
{
// nothing
}
// helper methods (protected)
// clips (top/bottom) or (right/left) edges against the frame's bounding rect.
void do_clip_edges( int len, int& rectPos, int& rectLen )
{
if ( rectPos < 0 )
{
rectLen += rectPos;
rectPos = 0;
if ( rectLen < 0 )
rectLen = 1;
}
else
if ( rectPos > len-1 )
{
rectPos = len-1;
rectLen = 1;
}
else
if ( rectPos + rectLen - 1 > len )
rectLen -= (rectPos + rectLen) - len + 1;
}
void cbBarDragPlugin::ClipRectInFrame( wxRect& rect )
{
int w, h;
mpLayout->GetParentFrame().GetClientSize( &w, &h );
do_clip_edges( w, rect.x, rect.width );
do_clip_edges( h, rect.y, rect.height );
}
void cbBarDragPlugin::ClipPosInFrame( wxPoint& pos )
{
int w, h;
mpLayout->GetParentFrame().GetClientSize( &w, &h );
if ( pos.x < 0 )
pos.x = 0;
if ( pos.y < 0 )
pos.y = 0;
if ( pos.x > w )
pos.x = w-1;
if ( pos.y > h )
pos.y = h-1;
}
void cbBarDragPlugin::AdjustHintRect( wxPoint& mousePos )
{
mHintRect.x = mousePos.x - mMouseInRectX;
mHintRect.y = mousePos.y - mMouseInRectY;
}
cbDockPane* cbBarDragPlugin::HitTestPanes( wxRect& rect )
{
//wxRect clipped = rect;
//ClipRectInFrame( clipped );
cbDockPane** pPanes = mpLayout->GetPanesArray();
for( int i = 0; i != MAX_PANES; ++i )
if ( rect_hits_rect( pPanes[i]->mBoundsInParent, rect ) )
return pPanes[i];
return NULL;
}
cbDockPane* cbBarDragPlugin::HitTestPanes( wxPoint& pos )
{
wxPoint clipped = pos;
//ClipPosInFrame( pos );
cbDockPane** pPanes = mpLayout->GetPanesArray();
for( int i = 0; i != MAX_PANES; ++i )
if ( rect_contains_point( pPanes[i]->mBoundsInParent, clipped.x, clipped.y ) )
return pPanes[i];
return NULL;
}
bool cbBarDragPlugin::HitsPane( cbDockPane* pPane, wxRect& rect )
{
return rect_hits_rect( pPane->mBoundsInParent, rect );
}
int cbBarDragPlugin::GetDistanceToPane( cbDockPane* pPane, wxPoint& mousePos )
{
wxRect& bounds = pPane->mBoundsInParent;
switch( pPane->mAlignment )
{
case FL_ALIGN_TOP : return mousePos.y - ( bounds.y + bounds.height );
case FL_ALIGN_BOTTOM : return bounds.y - mousePos.y;
case FL_ALIGN_LEFT : return mousePos.x - ( bounds.x + bounds.width );
case FL_ALIGN_RIGHT : return bounds.x - mousePos.x;
default : return 0; // never reached
}
// return 0;
}
bool cbBarDragPlugin::IsInOtherPane( wxPoint& mousePos )
{
cbDockPane* pPane = HitTestPanes( mousePos );
if ( pPane && pPane != mpCurPane ) return TRUE;
else return FALSE;
}
bool cbBarDragPlugin::IsInClientArea( wxPoint& mousePos )
{
return ( HitTestPanes( mousePos ) == NULL );
}
bool cbBarDragPlugin::IsInClientArea( wxRect& rect )
{
return ( HitTestPanes( rect ) == NULL );
}
void cbBarDragPlugin::CalcOnScreenDims( wxRect& rect )
{
if ( !mpCurPane || mpDraggedBar->IsFixed() ) return;
wxRect inPane = rect;
mpCurPane->FrameToPane( &inPane );
int rowNo = mpCurPane->GetRowAt( inPane.y, inPane.y + inPane.height );
bool isMaximized = ( rowNo >= (int)mpCurPane->GetRowList().Count() || rowNo < 0 );
if ( isMaximized )
{
inPane.x = 0;
inPane.width = mpCurPane->mPaneWidth;
mpCurPane->PaneToFrame( &inPane );
rect = inPane;
}
}
// helpers
static inline void check_upper_overrun( int& pos, int width, int mousePos )
{
if ( mousePos >= pos + width )
pos = mousePos - width/2;
}
static inline void check_lower_overrun( int& pos, int width, int mousePos )
{
if ( mousePos <= pos )
pos = mousePos - width/2;
}
void cbBarDragPlugin::StickToPane( cbDockPane* pPane, wxPoint& mousePos )
{
int wInPane = GetBarWidthInPane ( pPane );
int hInPane = GetBarHeightInPane( pPane );
// adjsut hint-rect horizontally (in pane's orientation)
if ( pPane->IsHorizontal() )
{
mHintRect.width = wInPane;
mHintRect.height = hInPane;
}
else
{
mHintRect.height = wInPane;
mHintRect.width = hInPane;
}
// adjsut hint-rect vertically (in pane's orientation)
wxRect& bounds = pPane->mBoundsInParent;
// TRUE, if hint enters the pane through it's lower edge
bool fromLowerEdge = ( pPane->IsHorizontal() )
? mousePos.y > bounds.y
: mousePos.x > bounds.x;
// NOTE:: about all the below min/max things: they are meant to ensure
// that mouse pointer doesn't overrun (leave) the hint-rectangle
// when dimensions it's are recalculated upon sticking it to the pane
if ( pPane->IsHorizontal() && fromLowerEdge )
{
int paneBottomEdgeY = bounds.y + bounds.height;
mHintRect.y = wxMin( paneBottomEdgeY, mousePos.y );
check_lower_overrun( mHintRect.y, hInPane, mousePos.y );
}
else
if ( pPane->IsHorizontal() && !fromLowerEdge )
{
int paneTopEdgeY = bounds.y;
mHintRect.y = wxMax( paneTopEdgeY - hInPane, mousePos.y - hInPane );
check_upper_overrun( mHintRect.y, hInPane, mousePos.y );
}
else
if ( !pPane->IsHorizontal() && fromLowerEdge )
{
int paneRightEdgeX = bounds.x + bounds.width;
mHintRect.x = wxMin( paneRightEdgeX, mousePos.x );
check_lower_overrun( mHintRect.x, hInPane, mousePos.x );
}
else
if ( !pPane->IsHorizontal() && !fromLowerEdge )
{
int paneLeftEdgeX = bounds.x;
mHintRect.x = wxMax( paneLeftEdgeX - hInPane, mousePos.x - hInPane );
check_upper_overrun( mHintRect.x, hInPane, mousePos.x );
}
mMouseInRectX = mousePos.x - mHintRect.x;
mMouseInRectY = mousePos.y - mHintRect.y;
mpCurPane = pPane; // memorize pane to which the hint is currently sticked
}
void cbBarDragPlugin::UnstickFromPane( cbDockPane* pPane, wxPoint& mousePos )
{
// unsticking causes rectangle to get the shape, in which
// dragged control-bar would be when floated
int newWidth = mpDraggedBar->mDimInfo.mSizes[wxCBAR_FLOATING].x;
int newHeight = mpDraggedBar->mDimInfo.mSizes[wxCBAR_FLOATING].y;
wxRect& flBounds = mpDraggedBar->mDimInfo.mBounds[wxCBAR_FLOATING];
if ( flBounds.width != -1 )
{
newWidth = flBounds.width;
newHeight = flBounds.height;
}
mHintRect.width = newWidth;
mHintRect.height = newHeight;
wxRect& bounds = pPane->mBoundsInParent;
// TRUE, if hint leaves the pane through it's lower edge
bool fromLowerEdge = ( pPane->IsHorizontal() )
? mousePos.y > bounds.y
: mousePos.x > bounds.x;
// NOTE:: ...all the below min/max things - see comments about it in StickToPane(..)
if ( pPane->IsHorizontal() && fromLowerEdge )
{
// bool fromLowerEdge = mousePos.y > bounds.y;
mHintRect.y = wxMax( bounds.y + bounds.height + 1, mousePos.y - newHeight );
check_upper_overrun( mHintRect.y, newHeight, mousePos.y );
// this is how MFC's hint behaves:
if ( mMouseInRectX > newWidth )
mHintRect.x = mousePos.x - ( newWidth / 2 );
}
else
if ( pPane->IsHorizontal() && !fromLowerEdge )
{
mHintRect.y = wxMin( bounds.y - newHeight - 1, mousePos.y );
// -/-
if ( mMouseInRectX > newWidth )
mHintRect.x = mousePos.x - ( newWidth / 2 );
check_lower_overrun( mHintRect.y, newHeight, mousePos.y );
}
else
if ( !pPane->IsHorizontal() && fromLowerEdge )
{
mHintRect.x = wxMax( bounds.x + bounds.width, mousePos.x - newWidth );
// -/-
if ( mMouseInRectY > newHeight )
mHintRect.y = mousePos.y - ( newHeight / 2 );
check_upper_overrun( mHintRect.x, newWidth, mousePos.x );
}
else
if ( !pPane->IsHorizontal() && !fromLowerEdge )
{
mHintRect.x = wxMin( bounds.x - newWidth - 1, mousePos.x );
// -/-
if ( mMouseInRectY > newHeight )
mHintRect.y = mousePos.y - ( newHeight / 2 );
check_lower_overrun( mHintRect.x, newWidth, mousePos.x );
}
mMouseInRectX = mousePos.x - mHintRect.x;
mMouseInRectY = mousePos.y - mHintRect.y;
mpCurPane = NULL;
}
int cbBarDragPlugin::GetBarWidthInPane( cbDockPane* pPane )
{
if ( pPane == mpSrcPane )
return mBarWidthInSrcPane;
// this is how MFC's bars behave:
if ( pPane->IsHorizontal() )
return mpDraggedBar->mDimInfo.mSizes[wxCBAR_DOCKED_HORIZONTALLY].x;
else
return mpDraggedBar->mDimInfo.mSizes[wxCBAR_DOCKED_VERTICALLY ].x;
}
int cbBarDragPlugin::GetBarHeightInPane( cbDockPane* pPane )
{
if ( pPane->IsHorizontal() )
return mpDraggedBar->mDimInfo.mSizes[wxCBAR_DOCKED_HORIZONTALLY].y;
else
return mpDraggedBar->mDimInfo.mSizes[wxCBAR_DOCKED_VERTICALLY ].y;
}
void cbBarDragPlugin::ShowHint( bool prevWasInClient )
{
bool wasDocked = FALSE;
if ( mpDraggedBar->mState != wxCBAR_FLOATING && !mpCurPane )
{
mpLayout->SetBarState( mpDraggedBar, wxCBAR_FLOATING, TRUE );
}
else
if ( mpDraggedBar->mState == wxCBAR_FLOATING && mpCurPane )
{
mpLayout->SetBarState( mpDraggedBar, wxCBAR_DOCKED_HORIZONTALLY, FALSE );
wasDocked = TRUE;
}
if ( mpSrcPane->mProps.mRealTimeUpdatesOn == FALSE )
{
// do hevy calculations first
wxRect actualRect = mHintRect; // will be adjusted depending on drag-settings
if ( mpSrcPane->mProps.mExactDockPredictionOn && mpCurPane )
{
bool success = mpLayout->RedockBar( mpDraggedBar, mHintRect, mpCurPane, FALSE );
wxASSERT( success ); // DBG::
actualRect = mpDraggedBar->mBounds;
mpCurPane->PaneToFrame( &actualRect );
}
else
CalcOnScreenDims( actualRect );
// release previous hint
if ( mPrevHintRect.x != POS_UNDEFINED )
{
// erase previous rectangle
cbDrawHintRectEvent evt( mPrevHintRect, prevWasInClient, TRUE, FALSE );
mpLayout->FirePluginEvent( evt );
}
// draw new hint
cbDrawHintRectEvent evt( actualRect, mpCurPane == NULL, FALSE, FALSE );
mpLayout->FirePluginEvent( evt );
mPrevHintRect = actualRect;
}
else
{
// otherwise, if real-time updates option is ON
if ( mpCurPane )
{
mpLayout->GetUpdatesManager().OnStartChanges();
if ( wasDocked )
mpDraggedBar->mUMgrData.SetDirty( TRUE );
bool success = mpLayout->RedockBar( mpDraggedBar, mHintRect, mpCurPane, FALSE );
wxASSERT( success ); // DBG ::
mpLayout->GetUpdatesManager().OnFinishChanges();
mpLayout->GetUpdatesManager().UpdateNow();
}
else
{
if ( mpLayout->mFloatingOn )
{
// move the top-most floated bar around as user drags the hint
mpDraggedBar->mDimInfo.mBounds[ wxCBAR_FLOATING ] = mHintRect;
mpLayout->ApplyBarProperties( mpDraggedBar );
}
}
}
}
/*** event handlers ***/
void cbBarDragPlugin::OnMouseMove( cbMotionEvent& event )
{
// calculate postion in frame's coordiantes
if ( !mBarDragStarted )
{
event.Skip(); // pass event to the next plugin
return;
}
wxPoint mousePos = event.mPos;
event.mpPane->PaneToFrame( &mousePos.x, &mousePos.y );
bool prevIsInClient = ( mpCurPane == 0 );
AdjustHintRect( mousePos );
// if the hint-rect is not "tempted" to any pane yet
if ( mpCurPane == NULL )
{
cbDockPane* pPane = HitTestPanes( mHintRect );
if ( !pPane )
// enable sticking again, if we've left the pane completely
mCanStick = TRUE;
if ( mCanStick && pPane &&
GetDistanceToPane( pPane, mousePos ) < GetBarHeightInPane( pPane ) )
StickToPane( pPane, mousePos );
else
if ( pPane && HitTestPanes( mousePos ) == pPane && 0 ) // FOR NOW:: disabled
StickToPane( pPane, mousePos );
}
else
{
// otherwise, when rect is now sticked to some of the panes
// check if it should still remain in this pane
mCanStick = TRUE;
bool mouseInOther = IsInOtherPane( mousePos );
if ( mouseInOther )
{
cbDockPane* pPane = HitTestPanes( mousePos );
StickToPane( pPane, mousePos );
}
else
{
if ( IsInClientArea( mousePos ) )
{
cbDockPane* pPane = HitTestPanes( mHintRect );
if ( pPane &&
pPane != mpCurPane &&
GetDistanceToPane( pPane, mousePos ) < GetBarHeightInPane( pPane ) )
StickToPane( pPane, mousePos );
else
if ( !pPane )
{
UnstickFromPane( mpCurPane, mousePos );
// FOR NOW:: disabled, would cause some mess
//mCanStick = FALSE; // prevents from sticking to this
// pane again, flag is reset when hint-rect
// leaves the pane completely
}
else
if ( GetDistanceToPane( pPane, mousePos ) > GetBarHeightInPane( pPane ) )
{
if ( !HitsPane( mpCurPane, mHintRect ) )
{
UnstickFromPane( mpCurPane, mousePos );
// FOR NOW:: disabled, would cause some mess
//mCanStick = FALSE; // prevents from sticking to this
// pane again, flag is reset when hint-rect
// leaves the pane completely
}
}
}
else
{
}
}
}
ShowHint( prevIsInClient );
wxCursor* pPrevCurs = mpCurCursor;
if ( mpCurPane )
mpCurCursor = mpLayout->mpDragCursor;
else
{
if ( mpLayout->mFloatingOn && mpSrcPane->mProps.mRealTimeUpdatesOn )
mpCurCursor = mpLayout->mpDragCursor;
else
mpCurCursor = mpLayout->mpNECursor;
}
if ( pPrevCurs != mpCurCursor )
mpLayout->GetParentFrame().SetCursor( *mpCurCursor );
}
void cbBarDragPlugin::OnLButtonDown( cbLeftDownEvent& event )
{
if ( mBarDragStarted )
{
wxMessageBox("DblClick!");
}
event.Skip();
}
void cbBarDragPlugin::OnLButtonUp( cbLeftUpEvent& event )
{
if ( mBarDragStarted )
{
if ( mpSrcPane->mProps.mRealTimeUpdatesOn == FALSE )
{
// erase current rectangle, and finsih on-screen drawing session
cbDrawHintRectEvent evt( mPrevHintRect, mpCurPane == NULL, TRUE, TRUE );
mpLayout->FirePluginEvent( evt );
if ( mpCurPane != NULL )
{
if ( mpSrcPane->mProps.mExactDockPredictionOn )
{
mpLayout->RedockBar( mpDraggedBar, mHintRect, mpCurPane, FALSE );
mpLayout->GetUpdatesManager().OnFinishChanges();
mpLayout->GetUpdatesManager().UpdateNow();
}
else
mpLayout->RedockBar( mpDraggedBar, mHintRect, mpCurPane );
}
}
mHintRect.width = -1;
mpLayout->GetParentFrame().SetCursor( *mpLayout->mpNormalCursor );
mpLayout->ReleaseEventsFromPane( event.mpPane );
mpLayout->ReleaseEventsFromPlugin( this );
mBarDragStarted = FALSE;
if ( mBarWasFloating && mpDraggedBar->mState != wxCBAR_FLOATING )
{
// save bar's floating position before it was docked
mpDraggedBar->mDimInfo.mBounds[ wxCBAR_FLOATING ] = mFloatedBarBounds;
}
}
else
event.Skip(); // pass event to the next plugin
}
void cbBarDragPlugin::OnLDblClick( cbLeftDClickEvent& event )
{
int avoidCompilerWarning = 1;
if ( avoidCompilerWarning )
{
cbBarInfo* pHittedBar;
cbRowInfo* pRow;
if ( event.mpPane->HitTestPaneItems( event.mPos, // in pane's coordiantes
&pRow,
&pHittedBar ) == CB_BAR_CONTENT_HITTED
)
{
mpLayout->SetBarState( pHittedBar, wxCBAR_FLOATING, TRUE );
mpLayout->RepositionFloatedBar( pHittedBar );
return; // event is "eaten" by this plugin
}
mBarDragStarted = FALSE;
event.Skip();
}
//wxMessageBox("Hi, dblclick arrived!");
}
void cbBarDragPlugin::OnStartBarDragging( cbStartBarDraggingEvent& event )
{
mpDraggedBar = event.mpBar;
mpSrcPane = event.mpPane;
mpLayout->CaptureEventsForPane( event.mpPane );
mpLayout->CaptureEventsForPlugin( this );
mpLayout->GetParentFrame().SetCursor( *mpLayout->mpDragCursor );
mBarDragStarted = TRUE;
wxRect inParent = mpDraggedBar->mBounds;
mBarWasFloating = mpDraggedBar->mState == wxCBAR_FLOATING;
if ( mBarWasFloating )
{
inParent = mpDraggedBar->mDimInfo.mBounds[ wxCBAR_FLOATING ];
mFloatedBarBounds = inParent;
}
else
event.mpPane->PaneToFrame( &inParent );
mHintRect.x = POS_UNDEFINED;
mHintRect.width = inParent.width;
mHintRect.height = inParent.height;
mMouseInRectX = event.mPos.x - inParent.x;
mMouseInRectY = event.mPos.y - inParent.y;
mpSrcPane = event.mpPane;
if ( mpDraggedBar->mState == wxCBAR_FLOATING )
mpCurPane = NULL;
else
mpCurPane = event.mpPane;
mPrevHintRect.x = POS_UNDEFINED;
mCanStick = FALSE; // we're not stuck into any pane now -
// there's nowhere to "stick-twice"
mBarWidthInSrcPane = mpDraggedBar->mDimInfo.mSizes[ mpDraggedBar->mState ].x;
if ( mpSrcPane->mProps.mRealTimeUpdatesOn == FALSE &&
mpSrcPane->mProps.mExactDockPredictionOn )
mpLayout->GetUpdatesManager().OnStartChanges(); // capture initial state of layout
// simulate the first mouse movement
int x = event.mPos.x, y = event.mPos.y;
mpSrcPane->FrameToPane( &x, &y );
cbMotionEvent motionEvt( wxPoint(x,y), event.mpPane );
this->OnMouseMove( motionEvt );
return; // event is "eaten" by this plugin
}
/*** on-screen hint-tracking related methods ***/
void cbBarDragPlugin::OnDrawHintRect( cbDrawHintRectEvent& event )
{
if ( !mpScrDc ) StartTracking();
DoDrawHintRect( event.mRect, event.mIsInClient );
if ( event.mLastTime )
FinishTracking();
}
#define _IMG_A 0xAA // Note: modified from _A to _IMG_A, _A was already defined (cygwin)
#define _IMG_B 0x00 // Note: modified from _B to _IMG_A, _B was already defined (cygwin)
#define _IMG_C 0x55 // Note: modified from _C to _IMG_C, for consistency reasons.
#define _IMG_D 0x00 // Note: modified from _D to _IMG_D, for consistency reasons.
// FOR NOW:: static
static const unsigned char _gCheckerImg[16] = { _IMG_A,_IMG_B,_IMG_C,_IMG_D,
_IMG_A,_IMG_B,_IMG_C,_IMG_D,
_IMG_A,_IMG_B,_IMG_C,_IMG_D,
_IMG_A,_IMG_B,_IMG_C,_IMG_D
};
void cbBarDragPlugin::StartTracking()
{
mpScrDc = new wxScreenDC;
wxScreenDC::StartDrawingOnTop(&mpLayout->GetParentFrame());
}
void cbBarDragPlugin::DoDrawHintRect( wxRect& rect, bool isInClientRect)
{
wxRect scrRect;
RectToScr( rect, scrRect );
int prevLF = mpScrDc->GetLogicalFunction();
mpScrDc->SetLogicalFunction( wxINVERT );
if ( isInClientRect )
{
// BUG BUG BUG (wx):: somehow stippled brush works only
// when the bitmap created on stack, not
// as a member of the class
wxBitmap checker( (const char*)_gCheckerImg, 8,8 );
wxBrush checkerBrush( checker );
mpScrDc->SetPen( mpLayout->mNullPen );
mpScrDc->SetBrush( checkerBrush );
int half = mInClientHintBorder / 2;
mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y - half,
scrRect.width + 2*half, mInClientHintBorder );
mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y + scrRect.height - half,
scrRect.width + 2*half, mInClientHintBorder );
mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y + half - 1,
mInClientHintBorder, scrRect.height - 2*half + 2);
mpScrDc->DrawRectangle( scrRect.x + scrRect.width - half,
scrRect.y + half - 1,
mInClientHintBorder, scrRect.height - 2*half + 2);
mpScrDc->SetBrush( wxNullBrush );
}
else
{
mpScrDc->SetPen( mpLayout->mBlackPen );
mpScrDc->DrawLine( scrRect.x, scrRect.y,
scrRect.x + scrRect.width, scrRect.y );
mpScrDc->DrawLine( scrRect.x, scrRect.y + 1,
scrRect.x, scrRect.y + scrRect.height );
mpScrDc->DrawLine( scrRect.x+1, scrRect.y + scrRect.height,
scrRect.x + scrRect.width, scrRect.y + scrRect.height );
mpScrDc->DrawLine( scrRect.x + scrRect.width , scrRect.y,
scrRect.x + scrRect.width, scrRect.y + scrRect.height + 1);
}
mpScrDc->SetLogicalFunction( prevLF );
}
void cbBarDragPlugin::DrawHintRect ( wxRect& rect, bool isInClientRect)
{
DoDrawHintRect( rect, isInClientRect );
}
void cbBarDragPlugin::EraseHintRect( wxRect& rect, bool isInClientRect)
{
DoDrawHintRect( rect, isInClientRect );
}
void cbBarDragPlugin::FinishTracking()
{
wxScreenDC::EndDrawingOnTop();
delete mpScrDc;
mpScrDc = NULL;
}
void cbBarDragPlugin::RectToScr( wxRect& frameRect, wxRect& scrRect )
{
scrRect = frameRect;
int x = frameRect.x, y = frameRect.y;
mpLayout->GetParentFrame().ClientToScreen( &x, &y );
scrRect.x = x;
scrRect.y = y;
}