package Ġcom . dan . simp ler aw camera Ċ Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . res . Resources Ċ import Ġandroid . graphics . Canvas Ċ import Ġandroid . graphics . Color Ċ import Ġandroid . graphics . Rect Ċ import Ġandroid . util . Attribute Set Ċ import Ġandroid . view . Motion Event Ċ import Ġandroidx . appcompat . widget . AppCompat TextView Ċ import Ġkotlin . math . abs ĊĊ Ċ /** Ċ ĠSim ulate Ġa Ġbutton Ġwith Ġup / down Ġand / or Ġleft / right Ġmov ements Ċ Ġ*/ Ċ class ĠS ensitive TextView Ġ: ĠAppCompat TextView Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġdp To Px ( dp : ĠInt ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ( dp Ġ* ĠResources . getSystem (). display Metrics . density ). toInt () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval ĠP ADDING Ġ= Ġdp To Px ( 1 ). toFloat () ĊĊĠĠĠĠĠĠĠ Ġval ĠBG _ COLOR _ NORMAL Ġ= ĠColor . arg b ( 0 x 8 0 , Ġ 0 , Ġ 0 , Ġ 0 Ġ) ĊĠĠĠĠĠĠĠ Ġval ĠBG _ COLOR _ PRES SED Ġ= ĠColor . rgb ( 4 8 , Ġ 4 8 , Ġ 4 8 Ġ) ĊĊĠĠĠĠĠĠĠ Ġval ĠSTEP _ X Ġ= Ġdp To Px ( 3 0 ) ĊĠĠĠĠĠĠĠ Ġval ĠSTEP _ Y Ġ= Ġdp To Px ( 5 0 ) ĊĊĠĠĠĠĠĠĠ Ġconst Ġval ĠDI RECTION _ NONE Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠDI RECTION _ NOT _ DEFINED Ġ= Ġ 1 ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠDI RECTION _ X _ AXIS Ġ= Ġ 2 ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠDI RECTION _ Y _ AXIS Ġ= Ġ 3 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġm Start X : ĠFloat Ġ= Ġ 0 f ĊĠĠĠ Ġprivate Ġvar Ġm Start Y : ĠFloat Ġ= Ġ 0 f ĊĠĠĠ Ġprivate Ġvar Ġm Direction : ĠInt Ġ= ĠDI RECTION _ NONE ĊĠĠĠ Ġprivate Ġvar Ġm On Move X Axis : Ġ(( Int )-> Unit )? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġm On Move Y Axis : Ġ(( Int )-> Unit )? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġval Ġm Text Rect Ġ= ĠRect () ĊĊĠĠĠ Ġconstructor ( context : ĠContext ) Ġ: Ġsuper ( context , Ġnull ) Ġ{ Ġinit () Ġ} ĊĠĠĠ Ġconstructor ( context : ĠContext , Ġattrs : ĠAttributeSet ?) Ġ: Ġsuper ( context , Ġattrs , Ġ 0 ) Ġ{ Ġinit () Ġ} ĊĠĠĠ Ġconstructor ( context : ĠContext , Ġattrs : ĠAttributeSet ?, Ġdef Style Attr : ĠInt ) Ġ: Ġsuper ( context , Ġattrs , Ġdef Style Attr ) Ġ{ Ġinit () Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġinit () Ġ{ ĊĠĠĠĠĠĠĠ Ġset BackgroundColor ( BG _ COLOR _ NORMAL ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Draw ( canvas : ĠCanvas ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Draw ( canvas ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( null Ġ== Ġcanvas ) Ġreturn ĊĊĠĠĠĠĠĠĠ Ġvar Ġchar Left Ġ= Ġ" +" ĊĠĠĠĠĠĠĠ Ġvar Ġchar Right Ġ= Ġ" +" ĊĠĠĠĠĠĠĠ Ġvar Ġchar Right Is Rot ated Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġvar Ġchar Offset Ġ= Ġ 0 ĊĊĠĠĠĠĠĠĠ Ġif Ġ( DIRECTION _ X _ AXIS Ġ== Ġm Direction Ġ|| Ġ( DIRECTION _ NONE Ġ== Ġm Direction Ġ&& Ġnull Ġ!= Ġm On Move X Axis Ġ&& Ġnull Ġ== Ġm On Move Y Axis )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchar Left Ġ= Ġ"< " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchar Right Ġ= Ġ" >" ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( DIRECTION _ Y _ AXIS Ġ== Ġm Direction Ġ|| Ġ( DIRECTION _ NONE Ġ== Ġm Direction Ġ&& Ġnull Ġ== Ġm On Move X Axis Ġ&& Ġnull Ġ!= Ġm On Move Y Axis )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchar Left Ġ= Ġ"^ " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchar Right Ġ= Ġ"^ " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchar Right Is Rot ated Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchar Offset Ġ= Ġdp To Px ( 5 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġpaint Ġ= Ġthis . paint ĊĊĠĠĠĠĠĠĠ Ġpaint . getText Bounds ( Ġchar Left , Ġ 0 , Ġ 1 , Ġm Text Rect Ġ) ĊĠĠĠĠĠĠĠ Ġcanvas . draw Text ( Ġchar Left , ĠP ADDING , Ġ( height Ġ+ Ġm Text Rect . height ()) Ġ/ Ġ 2 f Ġ+ Ġchar Offset , Ġpaint Ġ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( char Right Is Rot ated ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas . rotate ( 1 8 0 f , Ġwidth Ġ- Ġ( P ADDING Ġ+ Ġm Text Rect . width ()) Ġ/ Ġ 2 , Ġheight Ġ/ Ġ 2 f ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcanvas . draw Text ( Ġchar Right , Ġwidth Ġ- ĠP ADDING Ġ- Ġm Text Rect . width (), Ġ( height Ġ+ Ġm Text Rect . height ()) Ġ/ Ġ 2 f Ġ+ Ġchar Offset , Ġpaint Ġ) ĊĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Touch Event ( ev : ĠMotion Event ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen ( ev . action ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMotion Event . ACTION _ DOWN Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Action Down ( ev ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠMotion Event . ACTION _ MOVE Ġ-> Ġhandle Action Move ( ev ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMotion Event . ACTION _ UP Ġ-> Ġhandle Action Up () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġsuper . on Touch Event ( ev ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandle Action Move ( ev : ĠMotion Event ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdelta X Ġ= Ġ( ev . x Ġ- Ġm Start X ). toInt () ĊĠĠĠĠĠĠĠ Ġval Ġdelta Y Ġ= Ġ( ev . y Ġ- Ġm Start Y ). toInt () ĊĠĠĠĠĠĠĠ Ġval Ġabs Delta X Ġ= Ġabs ( delta X ) ĊĠĠĠĠĠĠĠ Ġval Ġabs Delta Y Ġ= Ġabs ( delta Y ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( DIRECTION _ NOT _ DEFINED Ġ== Ġm Direction Ġ|| ĠDI RECTION _ NONE Ġ== Ġm Direction ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( abs Delta X Ġ>= ĠSTEP _ X Ġ&& Ġnull Ġ!= Ġm On Move X Axis ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Direction Ġ= ĠDI RECTION _ X _ AXIS ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinvalidate () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( abs Delta Y Ġ>= ĠSTEP _ Y Ġ&& Ġnull Ġ!= Ġm On Move Y Axis ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Direction Ġ= ĠDI RECTION _ Y _ AXIS ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinvalidate () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġwhen ( m Direction ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDI RECTION _ X _ AXIS Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( abs Delta X Ġ>= ĠSTEP _ X ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsteps Ġ= Ġdelta X Ġ/ ĠSTEP _ X ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Start X Ġ= Ġev . x ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Start Y Ġ= Ġev . y ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm On Move X Axis ?. invoke ( steps ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠDI RECTION _ Y _ AXIS Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( abs Delta Y Ġ>= ĠSTEP _ Y ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsteps Ġ= Ġdelta Y Ġ/ ĠSTEP _ Y ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Start X Ġ= Ġev . x ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Start Y Ġ= Ġev . y ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm On Move Y Axis ?. invoke ( steps ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandle Action Down ( ev : ĠMotion Event ) Ġ{ ĊĠĠĠĠĠĠĠ Ġm Start X Ġ= Ġev . x ĊĠĠĠĠĠĠĠ Ġm Start Y Ġ= Ġev . y ĊĊĠĠĠĠĠĠĠ Ġm Direction Ġ= Ġif Ġ( null Ġ!= Ġm On Move X Axis Ġ&& Ġnull Ġ== Ġm On Move Y Axis ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDI RECTION _ X _ AXIS ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( null Ġ== Ġm On Move X Axis Ġ&& Ġnull Ġ!= Ġm On Move Y Axis ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDI RECTION _ Y _ AXIS ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDI RECTION _ NOT _ DEFINED ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġset BackgroundColor ( BG _ COLOR _ PRES SED ) ĊĠĠĠĠĠĠĠ Ġinvalidate () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandle Action Up () Ġ{ ĊĠĠĠĠĠĠĠ Ġm Direction Ġ= ĠDI RECTION _ NONE ĊĠĠĠĠĠĠĠ Ġset BackgroundColor ( BG _ COLOR _ NORMAL ) ĊĠĠĠĠĠĠĠ Ġinvalidate () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġset On Move X Axis Listener ( Ġl : Ġ( Int )-> Unit Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġm On Move X Axis Ġ= Ġl ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġset On Move Y Axis Listener ( Ġl : Ġ( Int )-> Unit Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġm On Move Y Axis Ġ= Ġl ĊĠĠĠ Ġ} Ċ }