]>
git.saurik.com Git - wxWidgets.git/blob - utils/framelayout/src/hintanimpl.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Contrib. demo
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleksandras Gluchovas
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "bardragpl.h"
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
28 #include "hintanimpl.h"
30 #define POS_UNDEFINED -32768
32 /***** Implementation for class cbHintAnimationPlugin *****/
34 // FIXME:: some of the below code should be eliminated by
35 // reusing parts of cbBarDragPlugin's implementation
37 IMPLEMENT_DYNAMIC_CLASS( cbHintAnimationPlugin
, cbPluginBase
)
39 BEGIN_EVENT_TABLE( cbHintAnimationPlugin
, cbPluginBase
)
41 EVT_PL_DRAW_HINT_RECT( cbHintAnimationPlugin::OnDrawHintRect
)
45 cbHintAnimationPlugin::cbHintAnimationPlugin(void)
48 mInClientHintBorder( 4 ),
49 mAnimStarted( FALSE
),
54 mAccelerationOn( TRUE
)
57 cbHintAnimationPlugin::cbHintAnimationPlugin( wxFrameLayout
* pPanel
, int paneMask
)
59 : cbPluginBase( pPanel
, paneMask
),
61 mInClientHintBorder( 4 ),
62 mAnimStarted( FALSE
),
67 mAccelerationOn( TRUE
)
70 cbHintAnimationPlugin::~cbHintAnimationPlugin()
72 if ( mpScrDc
) delete mpScrDc
;
75 /*** rect-tracking related methods ***/
77 void cbHintAnimationPlugin::OnDrawHintRect( cbDrawHintRectEvent
& event
)
79 if ( !mAnimStarted
&& !mpScrDc
)
83 mPrevInClient
= event
.mIsInClient
;
85 mPrevRect
= event
.mRect
;
90 if ( !event
.mEraseRect
)
92 // pass on current hint-rect info to the animation "thread", in
93 // order to make adjustments to the morph-target on-the-fly
95 mCurRect
.x
= event
.mRect
.x
;
96 mCurRect
.y
= event
.mRect
.y
;
97 mCurRect
.width
= event
.mRect
.width
;
98 mCurRect
.height
= event
.mRect
.height
;
101 // check the amount of change in the shape of hint,
102 // and start morph-effect if change is "sufficient"
104 int change
= abs( mCurRect
.width
- mPrevRect
.width
) +
105 abs( mCurRect
.height
- mPrevRect
.height
);
107 if ( change
> 10 && !event
.mLastTime
&& !event
.mEraseRect
)
111 mpAnimTimer
= new cbHintAnimTimer();
113 // init the animation "thread", or reinit if already started
121 mpAnimTimer
->Init( this, mAnimStarted
);
128 DoDrawHintRect( event
.mRect
, event
.mIsInClient
);
130 if ( event
.mLastTime
)
134 mPrevInClient
= event
.mIsInClient
;
138 mCurInClient
= event
.mIsInClient
;
140 if ( event
.mLastTime
&& mpAnimTimer
)
144 if ( mpAnimTimer
->mPrevMorphed
.x
!= POS_UNDEFINED
)
146 // erase previouse rect
147 DoDrawHintRect( mpAnimTimer
->mPrevMorphed
, mPrevInClient
);
151 mPrevRect
= event
.mRect
;
159 static const unsigned char _gCheckerImg
[] = { _A
,_B
,_C
,_D
,
165 void cbHintAnimationPlugin::StartTracking()
167 mpScrDc
= new wxScreenDC
;
169 wxScreenDC::StartDrawingOnTop(&mpLayout
->GetParentFrame());
172 void cbHintAnimationPlugin::DoDrawHintRect( wxRect
& rect
, bool isInClientRect
)
176 RectToScr( rect
, scrRect
);
178 int prevLF
= mpScrDc
->GetLogicalFunction();
180 mpScrDc
->SetLogicalFunction( wxXOR
);
182 if ( isInClientRect
)
184 // BUG BUG BUG (wx):: somehow stippled brush works only
185 // when the bitmap created on stack, not
186 // as a member of the class
188 wxBitmap
checker( (const char*)_gCheckerImg
, 8,8 );
190 wxBrush
checkerBrush( checker
);
192 mpScrDc
->SetPen( mpLayout
->mNullPen
);
193 mpScrDc
->SetBrush( checkerBrush
);
195 int half
= mInClientHintBorder
/ 2;
197 mpScrDc
->DrawRectangle( scrRect
.x
- half
, scrRect
.y
- half
,
198 scrRect
.width
+ 2*half
, mInClientHintBorder
);
200 mpScrDc
->DrawRectangle( scrRect
.x
- half
, scrRect
.y
+ scrRect
.height
- half
,
201 scrRect
.width
+ 2*half
, mInClientHintBorder
);
203 mpScrDc
->DrawRectangle( scrRect
.x
- half
, scrRect
.y
+ half
- 1,
204 mInClientHintBorder
, scrRect
.height
- 2*half
+ 2);
206 mpScrDc
->DrawRectangle( scrRect
.x
+ scrRect
.width
- half
,
207 scrRect
.y
+ half
- 1,
208 mInClientHintBorder
, scrRect
.height
- 2*half
+ 2);
210 mpScrDc
->SetBrush( wxNullBrush
);
214 // otherwise draw 1-pixel thin borders
216 mpScrDc
->SetPen( mpLayout
->mBlackPen
);
218 mpScrDc
->DrawLine( scrRect
.x
, scrRect
.y
,
219 scrRect
.x
+ scrRect
.width
, scrRect
.y
);
221 mpScrDc
->DrawLine( scrRect
.x
, scrRect
.y
+ 1,
222 scrRect
.x
, scrRect
.y
+ scrRect
.height
);
224 mpScrDc
->DrawLine( scrRect
.x
+1, scrRect
.y
+ scrRect
.height
,
225 scrRect
.x
+ scrRect
.width
, scrRect
.y
+ scrRect
.height
);
227 mpScrDc
->DrawLine( scrRect
.x
+ scrRect
.width
, scrRect
.y
,
228 scrRect
.x
+ scrRect
.width
, scrRect
.y
+ scrRect
.height
+ 1);
231 mpScrDc
->SetLogicalFunction( prevLF
);
234 void cbHintAnimationPlugin::DrawHintRect ( wxRect
& rect
, bool isInClientRect
)
236 DoDrawHintRect( rect
, isInClientRect
);
239 void cbHintAnimationPlugin::EraseHintRect( wxRect
& rect
, bool isInClientRect
)
241 DoDrawHintRect( rect
, isInClientRect
);
244 void cbHintAnimationPlugin::FinishTracking()
246 wxScreenDC::EndDrawingOnTop();
253 void cbHintAnimationPlugin::RectToScr( wxRect
& frameRect
, wxRect
& scrRect
)
257 int x
= frameRect
.x
, y
= frameRect
.y
;
259 mpLayout
->GetParentFrame().ClientToScreen( &x
, &y
);
265 /***** Implementation for class cbHintAnimTimer *****/
267 cbHintAnimTimer::cbHintAnimTimer(void)
273 mPrevMorphed
.x
= POS_UNDEFINED
;
276 void cbHintAnimTimer::MorphPoint( wxPoint
& origin
, MorphInfoT
& info
, wxPoint
& point
)
278 // simulate lienar movement (FOR NOW:: without acceleration)
282 if ( mpPl
->mAccelerationOn
)
284 k
= double( mCurIter
*mCurIter
) /
285 double( (mpPl
->mMaxFrames
- 1)*(mpPl
->mMaxFrames
- 1) );
287 k
= double( mCurIter
) / double( mpPl
->mMaxFrames
- 1 );
289 point
.x
= int ( double ( info
.mFrom
.x
+ double (info
.mTill
.x
- info
.mFrom
.x
) * k
) );
291 point
.y
= int ( double ( info
.mFrom
.y
+ double (info
.mTill
.y
- info
.mFrom
.y
) * k
) );
297 void cbHintAnimTimer::Notify(void)
299 // FIXME:: "clean" implementation should use mutex to sync
300 // between GUI and animation threads
302 if ( mpPl
->mStopPending
)
306 mpPl
->FinishTracking();
308 mpPl
->mStopPending
= FALSE
;
309 mpPl
->mpAnimTimer
= NULL
;
310 mpPl
->mAnimStarted
= FALSE
;
312 mPrevMorphed
.x
= POS_UNDEFINED
;
319 wxPoint
origin( mpPl
->mCurRect
.x
, mpPl
->mCurRect
.y
);
321 wxPoint curUpper
, curLower
;
323 MorphPoint( origin
, mUpperLeft
, curUpper
);
324 MorphPoint( origin
, mLowerRight
, curLower
);
326 if ( mPrevMorphed
.x
!= POS_UNDEFINED
)
328 // erase previouse rect
329 mpPl
->DoDrawHintRect( mPrevMorphed
, mpPl
->mPrevInClient
);
331 wxRect
morphed( curUpper
.x
, curUpper
.y
,
332 curLower
.x
- curUpper
.x
,
333 curLower
.y
- curUpper
.y
);
335 // draw rect of current iteration
336 mpPl
->DoDrawHintRect( morphed
,
337 ( mCurIter
!= mpPl
->mMaxFrames
- 1 )
338 ? mpPl
->mPrevInClient
: mpPl
->mCurInClient
);
340 mPrevMorphed
= morphed
;
342 if ( mCurIter
== mpPl
->mMaxFrames
- 1 )
346 mpPl
->FinishTracking();
347 mpPl
->mpAnimTimer
= NULL
;
348 mpPl
->mAnimStarted
= FALSE
;
350 mPrevMorphed
.x
= POS_UNDEFINED
;
358 bool cbHintAnimTimer::Init( cbHintAnimationPlugin
* pAnimPl
, bool reinit
)
366 // morph-points are set up relatively to the upper-left corner
367 // of the current hint-rectangle
371 mUpperLeft
.mFrom
.x
= mpPl
->mPrevRect
.x
- mpPl
->mCurRect
.x
;
372 mUpperLeft
.mFrom
.y
= mpPl
->mPrevRect
.y
- mpPl
->mCurRect
.y
;
374 mLowerRight
.mFrom
.x
= ( mUpperLeft
.mFrom
.x
+ mpPl
->mPrevRect
.width
);
375 mLowerRight
.mFrom
.y
= ( mUpperLeft
.mFrom
.y
+ mpPl
->mPrevRect
.height
);
379 wxPoint
origin( mpPl
->mPrevRect
.x
, mpPl
->mPrevRect
.y
);
381 wxPoint curUpper
, curLower
;
383 MorphPoint( origin
, mUpperLeft
, curUpper
);
384 MorphPoint( origin
, mLowerRight
, curLower
);
386 mUpperLeft
.mFrom
.x
= curUpper
.x
- mpPl
->mCurRect
.x
;
387 mUpperLeft
.mFrom
.y
= curUpper
.y
- mpPl
->mCurRect
.y
;
389 mLowerRight
.mFrom
.x
= ( mUpperLeft
.mFrom
.x
+ curLower
.x
- curUpper
.x
);
390 mLowerRight
.mFrom
.y
= ( mUpperLeft
.mFrom
.y
+ curLower
.y
- curUpper
.y
);
393 mUpperLeft
.mTill
.x
= 0;
394 mUpperLeft
.mTill
.y
= 0;
396 mLowerRight
.mTill
.x
= mpPl
->mCurRect
.width
;
397 mLowerRight
.mTill
.y
= mpPl
->mCurRect
.height
;
403 Start( mpPl
->mMorphDelay
);