/******************************************************************************* Ċ Ġ* ĠCopyright Ġ 2 0 1 1 , Ġ 2 0 1 2 ĠChris ĠB an es . Ċ Ġ* Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* Ċ Ġ* Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ package Ġcom . luck . picture . lib . photo view Ċ Ċ import Ġandroid . content .* Ċ import Ġandroid . view . Motion Event Ċ import Ġandroid . view . Scale Gesture Detector Ċ import Ġandroid . view . Scale Gesture Detector . On Scale Gesture Listener Ċ import Ġandroid . view . Velocity Tracker Ċ import Ġandroid . view . View Configuration Ċ Ċ /** Ċ Ġ* ĠDoes Ġa Ġwhole Ġlot Ġof Ġgesture Ġdetect ing . Ċ Ġ*/ Ċ internal Ġclass ĠCustom Gesture Detector ( context : ĠContext ?, Ġlistener : ĠOn Gesture Listener ) Ġ{ ĊĠĠĠ Ġprivate Ġvar Ġm Active Pointer Id Ġ= ĠINVALID _ POINTER _ ID ĊĠĠĠ Ġprivate Ġvar Ġm Active Pointer Index Ġ= Ġ 0 ĊĠĠĠ Ġprivate Ġval Ġm Detector : ĠScale Gesture Detector ĊĠĠĠ Ġprivate Ġvar Ġm Velocity Tracker : ĠVe locity Tracker ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġm Is Dragging Ġ= Ġfalse ĊĠĠĠ Ġprivate Ġvar Ġm Last Touch X Ġ= Ġ 0 f ĊĠĠĠ Ġprivate Ġvar Ġm Last Touch Y Ġ= Ġ 0 f ĊĠĠĠ Ġprivate Ġval Ġm Touch S lop : ĠFloat ĊĠĠĠ Ġprivate Ġval Ġm Minimum Velocity : ĠFloat ĊĠĠĠ Ġprivate Ġval Ġm Listener : ĠOn Gesture Listener ĊĠĠĠ Ġprivate Ġfun Ġget Active X ( ev : ĠMotion Event ): ĠFloat Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġev . getX ( m Active Pointer Index ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġev . x ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Active Y ( ev : ĠMotion Event ): ĠFloat Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġev . getY ( m Active Pointer Index ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġev . y ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġis Scaling (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġm Detector . is InProgress ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġis Dragging (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġm Is Dragging ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon Touch Event ( ev : ĠMotion Event ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Detector . on Touch Event ( ev ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprocess Touch Event ( ev ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIllegalArgumentException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFix Ġfor Ġsupport Ġlib Ġbug , Ġhappening Ġwhen Ġon Destroy Ġis Ġcalled ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġprocess Touch Event ( ev : ĠMotion Event ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġaction Ġ= Ġev . action ĊĠĠĠĠĠĠĠ Ġwhen Ġ( action Ġand ĠMotion Event . ACTION _ MASK ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMotion Event . ACTION _ DOWN Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Active Pointer Id Ġ= Ġev . get Pointer Id ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Velocity Tracker Ġ= ĠVe locity Tracker . obtain () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( null Ġ!= Ġm Velocity Tracker ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Velocity Tracker !!. add Movement ( ev ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Last Touch X Ġ= Ġget Active X ( ev ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Last Touch Y Ġ= Ġget Active Y ( ev ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Is Dragging Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMotion Event . ACTION _ MOVE Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġx Ġ= Ġget Active X ( ev ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġy Ġ= Ġget Active Y ( ev ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdx Ġ= Ġx Ġ- Ġm Last Touch X ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdy Ġ= Ġy Ġ- Ġm Last Touch Y ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! m Is Dragging ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠUse ĠPy th ag or as Ġto Ġsee Ġif Ġdrag Ġlength Ġis Ġlarger Ġthan ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġtouch Ġs lop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Is Dragging Ġ= ĠMath . sqrt (( dx Ġ* Ġdx Ġ+ Ġdy Ġ* Ġdy ). toDouble ()) Ġ>= Ġm Touch S lop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( m Is Dragging ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Listener . on Drag ( dx , Ġdy ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Last Touch X Ġ= Ġx ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Last Touch Y Ġ= Ġy ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( null Ġ!= Ġm Velocity Tracker ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Velocity Tracker !!. add Movement ( ev ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMotion Event . ACTION _ CANCEL Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Active Pointer Id Ġ= ĠINVALID _ POINTER _ ID ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRe cycle ĠVe locity ĠTracker ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( null Ġ!= Ġm Velocity Tracker ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Velocity Tracker !!. recycle () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Velocity Tracker Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMotion Event . ACTION _ UP Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Active Pointer Id Ġ= ĠINVALID _ POINTER _ ID ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( m Is Dragging ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( null Ġ!= Ġm Velocity Tracker ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Last Touch X Ġ= Ġget Active X ( ev ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Last Touch Y Ġ= Ġget Active Y ( ev ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCompute Ġvelocity Ġwithin Ġthe Ġlast Ġ 1 0 0 0 ms ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Velocity Tracker !!. add Movement ( ev ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Velocity Tracker !!. compute Current Velocity ( 1 0 0 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġv X Ġ= Ġm Velocity Tracker !!. x Velocity ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġv Y Ġ= Ġm Velocity Tracker !! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. y Velocity ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġthe Ġvelocity Ġis Ġgreater Ġthan Ġmin Velocity , Ġcall ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġlistener ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Math . max ( Math . abs ( v X ), ĠMath . abs ( vY )) Ġ>= Ġm Minimum Velocity ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Listener . on Fl ing ( m Last Touch X , Ġm Last Touch Y , Ġ- v X , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ- vY ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRe cycle ĠVe locity ĠTracker ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( null Ġ!= Ġm Velocity Tracker ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Velocity Tracker !!. recycle () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Velocity Tracker Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMotion Event . ACTION _ POINTER _ UP Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpointer Index : ĠInt Ġ= ĠUtil . get Pointer Index ( ev . action ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpointer Id Ġ= Ġev . get Pointer Id ( pointer Index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( pointer Id Ġ== Ġm Active Pointer Id ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThis Ġwas Ġour Ġactive Ġpointer Ġgoing Ġup . ĠChoose Ġa Ġnew ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġactive Ġpointer Ġand Ġadjust Ġaccordingly . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Pointer Index Ġ= Ġif Ġ( pointer Index Ġ== Ġ 0 ) Ġ 1 Ġelse Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Active Pointer Id Ġ= Ġev . get Pointer Id ( new Pointer Index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Last Touch X Ġ= Ġev . getX ( new Pointer Index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Last Touch Y Ġ= Ġev . getY ( new Pointer Index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġm Active Pointer Index Ġ= Ġev ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. find Pointer Index ( if Ġ( m Active Pointer Id Ġ!= ĠINVALID _ POINTER _ ID ) Ġm Active Pointer Id Ġelse Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠINVALID _ POINTER _ ID Ġ= Ġ- 1 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġconfiguration Ġ= ĠView Configuration ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. get ( context ) ĊĠĠĠĠĠĠĠ Ġm Minimum Velocity Ġ= Ġconfiguration . scaled Minimum Fl ing Velocity . toFloat () ĊĠĠĠĠĠĠĠ Ġm Touch S lop Ġ= Ġconfiguration . scaled Touch S lop . toFloat () ĊĠĠĠĠĠĠĠ Ġm Listener Ġ= Ġlistener ĊĠĠĠĠĠĠĠ Ġval Ġm Scale Listener : ĠOn Scale Gesture Listener Ġ= Ġobject Ġ: ĠOn Scale Gesture Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Scale ( detector : ĠScale Gesture Detector ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġscale Factor Ġ= Ġdetector . scale Factor ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( java . lang . Float . isNaN ( scale Factor ) Ġ|| Ġjava . lang . Float . isIn finite ( scale Factor )) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( scale Factor Ġ>= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Listener . on Scale ( scale Factor , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdetector . focus X , Ġdetector . focus Y ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Scale Begin ( detector : ĠScale Gesture Detector ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Scale End ( detector : ĠScale Gesture Detector ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠNO - OP ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġm Detector Ġ= ĠScale Gesture Detector ( context , Ġm Scale Listener ) ĊĠĠĠ Ġ} Ċ }