/* * Animation2.prg * Class file for animations components * * Copyright 2020 Ignacio Ortiz de Zúñiga * Copyright 2020 https://Xailer.com * All rights reserved * */ #include "Xailer.ch" #define EVENT_START 1 #define EVENT_PROCESS 2 #define EVENT_FINISH 3 CLASS XAniNumProperty FROM TAnimation PUBLISHED: PROPERTY cProperty INIT "" EDITOR PE_ControlNumericProperties PROPERTY oControl AS TControl EDITOR PE_ControlAnyLevel PROPERTY nStartValue INIT 0 PROPERTY nStopValue INIT 0 PROPERTY lForceRefresh INIT .F. PROPERTY lNcaRefresh INIT .F. PROPERTY lEnabled INIT .f. // forzado carga final PUBLIC: METHOD Start() PROTECTED: METHOD Synchro( nEventType, nValue ) METHOD CalcValues() END CLASS //-------------------------------------------------------------------------- METHOD Start() CLASS XAniNumProperty IF ::lCreated .AND. (::oControl == NIL .OR. Empty( ::cProperty ) .OR. ; !__objHasData( ::oControl, ::cProperty ) ) RETURN .f. ENDIF IF ::lStartFromCurrent .AND. ::oControl != NIL WITH OBJECT ::oControl ::nStartValue := __objSendMsg( ::oControl, ::cProperty ) END WITH ENDIF RETURN ::Super:Start() //-------------------------------------------------------------------------- METHOD Synchro( nEventType, nValue ) CLASS XAniNumProperty LOCAL lRet lRet := ::Super:Synchro( nEventType, @nValue ) IF (lRet == NIL .OR. lRet) .AND. nEventType = EVENT_PROCESS __objSendMsg( ::oControl, "_" + ::cProperty, nValue ) IF ::lForceRefresh IF !::lNcaRefresh InvalidateRect( ::oControl:Handle ) ELSE RedrawWindow( ::oControl:Handle, 0, 0, nOr( RDW_FRAME , RDW_INVALIDATE ) ) ENDIF ENDIF ENDIF RETURN NIL //-------------------------------------------------------------------------- METHOD CalcValues() CLASS XAniNumProperty LOCAL aValues LOCAL nFor, nLen, nBase, nOffs IF !::Super:CalcValues() RETURN .f. ENDIF aValues := ::aValues nLen := Len( aValues ) nBase := ::nStartValue nOffs := ::nStopValue - nBase FOR nFor := 1 TO nLen aValues[ nFor ] := nBase + ( nOffs * aValues[ nFor ] ) NEXT nFor ::aValues := aValues RETURN .T. //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- CLASS XAniControlSize FROM TAnimation PUBLISHED: PROPERTY oControl AS TControl EDITOR PE_ControlAnyLevel PROPERTY aStartValues INIT {0,0,0,0} EDITOR PE_RECT PROPERTY aStopValues INIT {0,0,0,0} EDITOR PE_RECT PROPERTY lForceRefresh INIT .F. PROPERTY lNcaRefresh INIT .F. PUBLIC: METHOD Start() PROTECTED: METHOD Synchro( nEventType, xValue ) METHOD CalcValues() END CLASS //-------------------------------------------------------------------------- METHOD Start() CLASS XAniControlSize IF ::lCreated .AND. (::oControl == NIL .OR. !__objHasMethod( ::oControl, "SetBounds" )) RETURN .f. ENDIF IF ::lStartFromCurrent .AND. ::oControl != NIL WITH OBJECT ::oControl ::aStartValues := { :nLeft, :nTop, :nWidth, :nHeight } END WITH ENDIF RETURN ::Super:Start() //-------------------------------------------------------------------------- METHOD Synchro( nEventType, xValue ) CLASS XAniControlSize LOCAL lRet lRet := ::Super:Synchro( nEventType, @xValue ) IF (lRet == NIL .OR. lRet) .AND. nEventType = EVENT_PROCESS ::oControl:SetBounds( xValue[ 1 ], xValue[ 2 ], xValue[ 3 ], xValue[ 4 ], .t. ) IF !::lNcaRefresh InvalidateRect( ::oControl:Handle ) ELSE RedrawWindow( ::oControl:Handle, 0, 0, nOr( RDW_FRAME , RDW_INVALIDATE ) ) ENDIF ENDIF RETURN NIL //-------------------------------------------------------------------------- METHOD CalcValues() CLASS XAniControlSize LOCAL aValues, aBase, aOffs, aTmp LOCAL nFor, nLen, nTmp IF !::Super:CalcValues() RETURN .f. ENDIF aValues := ::aValues aBase := aClone( ::aStartValues ) aOffs := aClone( ::aStopValues ) nLen := Len( aValues ) AEval( aOffs, {|v,e| aOffs[ e ] := v - aBase[ e ] } ) FOR nFor := 1 TO nLen aTmp := {0,0,0,0} FOR nTmp := 1 TO 4 aTmp[ nTmp ] := aBase[ nTmp ] + ( aOffs[ nTmp ] * aValues[ nFor ] ) NEXT nTmp aValues[ nFor ] := aTmp NEXT nFor ::aValues := aValues RETURN .T.