/* Ċ Ġ* ĠCopyright Ġ 2 0 2 1 ĠThe ĠAndroid ĠOpen ĠSource ĠProject Ċ Ġ* Ċ Ġ* Ġ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 Ġandroidx . compose . ui . focus Ċ Ċ import Ġandroidx . compose . runtime . collection . Mutable Vector Ċ import Ġandroidx . compose . ui . focus . Focus Direction . Companion . Down Ċ import Ġandroidx . compose . ui . focus . Focus Direction . Companion . Left Ċ import Ġandroidx . compose . ui . focus . Focus Direction . Companion . Right Ċ import Ġandroidx . compose . ui . focus . Focus Direction . Companion . Up Ċ import Ġandroidx . compose . ui . focus . Focus State Impl . Active Ċ import Ġandroidx . compose . ui . focus . Focus State Impl . Active Parent Ċ import Ġandroidx . compose . ui . focus . Focus State Impl . Capt ured Ċ import Ġandroidx . compose . ui . focus . Focus State Impl . De activated Ċ import Ġandroidx . compose . ui . focus . Focus State Impl . De activated Parent Ċ import Ġandroidx . compose . ui . focus . Focus State Impl . Inactive Ċ import Ġandroidx . compose . ui . geometry . Rect Ċ import Ġkotlin . math . absolute Value Ċ import Ġkotlin . math . max Ċ Ċ private Ġconst Ġval ĠInvalid Focus Direction Ġ= Ġ" This Ġfunction Ġshould Ġonly Ġbe Ġused Ġfor Ġ 2 - D Ġfocus Ġsearch " Ċ private Ġconst Ġval ĠNo Active Child Ġ= Ġ" Active Parent Ġmust Ġhave Ġa Ġfocused Child " Ċ Ċ /** Ċ Ġ* Ġ ĠPerform Ġa Ġsearch Ġamong Ġthe Ġimmediate Ġchildren Ġof Ġthis Ġ[ node ][ Focus Modifier ] Ġin Ġthe Ċ Ġ* Ġ Ġspecified Ġ[ direction ][ Focus Direction ] Ġand Ġreturn Ġthe Ġnode Ġthat Ġis Ġto Ġbe Ġfocused Ġnext . ĠIf Ġone Ċ Ġ* Ġ Ġof Ġthe Ġchildren Ġis Ġcurrently Ġfocused , Ġwe Ġstart Ġfrom Ġthat Ġpoint Ġand Ġsearch Ġin Ġthe Ġspecified Ċ Ġ* Ġ Ġ[ direction ][ Focus Direction ]. ĠIf Ġnone Ġof Ġthe Ġchildren Ġare Ġcurrently Ġfocused , Ġwe Ġpick Ġthe Ċ Ġ* Ġ Ġtop - left Ġor Ġbottom Ġright Ġbased Ġon Ġthe Ġspecified Ġ[ direction ][ Focus Direction ]. Ċ Ġ*/ Ċ internal Ġfun ĠFocus Modifier . two Dimension al Focus Search ( ĊĠĠĠ Ġdirection : ĠFocus Direction , ĊĠĠĠ Ġon Found : Ġ( Focus Modifier ) Ġ-> ĠBoolean Ċ ): ĠBoolean Ġ{ ĊĠĠĠ Ġwhen Ġ( focus State ) Ġ{ ĊĠĠĠĠĠĠĠ ĠIn active Ġ-> Ġreturn Ġon Found . invoke ( this ) ĊĠĠĠĠĠĠĠ ĠDe activated Ġ-> Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ ĠActive Parent , ĠDe activated Parent Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfocused Child Ġ= Ġfocused Child Ġ?: Ġerror ( No Active Child ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFor Ġ 2 D Ġfocus Ġsearch Ġwe Ġonly Ġsearch Ġamong Ġs iblings . ĠYou Ġhave Ġto Ġuse ĠD Pad ĠCenter Ġor ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcall Ġmove Focus ( In ) Ġto Ġmove Ġfocus Ġto Ġa Ġchild . ĠSo Ġtwo Dimension al Focus ĠSearch Ġdeleg ates ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġsearch Ġto Ġa Ġchild Ġonly Ġif Ġit Ġ" has Ġfocus ". ĠIf Ġthis Ġnode Ġ" is Ġfocused ", Ġwe Ġjust Ġskip Ġthe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġchildren Ġand Ġsearch Ġamong Ġthe Ġs iblings Ġof Ġthe Ġfocused Ġitem Ġby Ġcalling ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ" search Children " Ġon Ġthis Ġnode . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( focused Child . focus State ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġthe Ġfocused Child Ġis Ġan Ġintermediate Ġparent , Ġwe Ġcontinue Ġsearching Ġamong Ġits ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġchildren . ĠIf Ġwe Ġdon 't Ġfind Ġa Ġmatch , Ġwe Ġsearch Ġamong Ġthe Ġs iblings Ġof Ġthe Ġparent . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠActive Parent , ĠDe activated Parent Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfocused Child . two Dimension al Focus Search ( direction , Ġon Found ) Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsearch Children ( focused Child . active Node (), Ġdirection , Ġon Found ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSearch Ġfor Ġthe Ġnext Ġel igible Ġsibling . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠActive , ĠCapt ured Ġ-> Ġreturn Ġsearch Children ( focused Child , Ġdirection , Ġon Found ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDe activated , ĠIn active Ġ-> Ġerror ( No Active Child ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠActive , ĠCapt ured Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġ 2 - D Ġfocus Ġsearch Ġstarts Ġform Ġthe Ġroot . ĠIf Ġwe Ġreached Ġhere , Ġit Ġmeans Ġthat Ġthere ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwas Ġno Ġintermediate Ġnode Ġthat Ġwas ĠActive Parent . ĠThis Ġis Ġan Ġinitial Ġfocus Ġscenario . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWe Ġneed Ġto Ġsearch Ġamong Ġthis Ġnode 's Ġchildren Ġto Ġfind Ġthe Ġbest Ġfocus Ġcandidate . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġactivated Ġ= Ġactivated Children () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġthere Ġare Ġaren 't Ġmultiple Ġchildren Ġto Ġchoose Ġfrom , Ġreturn Ġthe Ġfirst Ġchild . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( activated . size Ġ<= Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġactivated . first OrNull ()?. let Ġ{ Ġon Found . invoke ( it ) Ġ} Ġ?: Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTo Ġstart Ġthe Ġsearch , Ġwe Ġpick Ġone Ġof Ġthe Ġfour Ġcorners Ġof Ġthis Ġnode Ġas Ġthe Ġinitially ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġfocused Ġrectangle . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinitial Focus Rect Ġ= Ġwhen Ġ( direction ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRight , ĠDown Ġ-> Ġfocus Rect (). top Left () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLeft , ĠUp Ġ-> Ġfocus Rect (). bottom Right () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror ( Invalid Focus Direction ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnext Candidate Ġ= Ġactivated . find Best Candidate ( initial Focus Rect , Ġdirection ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnext Candidate ?. let Ġ{ Ġon Found . invoke ( it ) Ġ} Ġ?: Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠFocus Modifier . search Children ( ĊĠĠĠ Ġfocused Item : ĠFocus Modifier , ĊĠĠĠ Ġdirection : ĠFocus Direction , ĊĠĠĠ Ġon Found : Ġ( Focus Modifier ) Ġ-> ĠBoolean Ċ ): ĠBoolean Ġ{ ĊĠĠĠ Ġval Ġchildren Copy Ġ= ĠMutable Vector < Focus Modifier >( children . size ) ĊĠĠĠ Ġchildren Copy . addAll ( children ) ĊĠĠĠ Ġwhile Ġ( children Copy . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġnext Item Ġ= Ġchildren Copy . find Best Candidate ( focused Item . focus Rect (), Ġdirection ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġreturn Ġfalse ĊĊĠĠĠĠĠĠĠ Ġ// ĠIf Ġthe Ġresult Ġis Ġnot Ġde activated , Ġthis Ġis Ġa Ġvalid Ġnext Ġitem . ĊĠĠĠĠĠĠĠ Ġif Ġ(! next Item . focus State . is De activated ) Ġreturn Ġon Found . invoke ( next Item ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠIf Ġthe Ġresult Ġis Ġde activated , Ġwe Ġsearch Ġamong Ġits Ġchildren . ĊĠĠĠĠĠĠĠ Ġif Ġ( next Item . search Children ( focused Item , Ġdirection , Ġon Found )) Ġreturn Ġtrue ĊĊĠĠĠĠĠĠĠ Ġ// ĠIf Ġthere Ġare Ġno Ġresults Ġamong Ġthe Ġchildren Ġof Ġthe Ġde activated Ġnode , ĊĠĠĠĠĠĠĠ Ġ// Ġrepeat Ġthe Ġsearch Ġby Ġexcluding Ġthis Ġde activated Ġnode . ĊĠĠĠĠĠĠĠ Ġchildren Copy . remove ( next Item ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġfalse Ċ } Ċ Ċ // ĠIterate Ġthrough Ġthis Ġlist Ġof Ġfocus Ġnodes Ġand Ġfind Ġbest Ġcandidate Ġin Ġthe Ġspecified Ġdirection . Ċ // ĠTODO ( b / 1 8 2 3 1 9 7 1 1 ): ĠFor ĠLeft / Right Ġfocus Ġmoves , ĠConsider Ġfinding Ġthe Ġfirst Ġcandidate Ġin Ġthe Ġbeam Ċ // Ġ Ġand Ġthen Ġonly Ġcomparing Ġcandidates Ġin Ġthe Ġbeam . ĠIf Ġnothing Ġis Ġin Ġthe Ġbeam , Ġthen Ġconsider Ġall Ċ // Ġ Ġvalid Ġcandidates . Ċ @ Suppress (" Modifier Factory Extension Function ", Ġ" Modifier Factory ReturnType ") Ċ private Ġfun ĠMutable Vector < Focus Modifier >. find Best Candidate ( ĊĠĠĠ Ġfocus Rect : ĠRect , ĊĠĠĠ Ġdirection : ĠFocus Direction Ċ ): ĠFocus Modifier ? Ġ{ ĊĠĠĠ Ġ// ĠPick Ġan Ġimpossible Ġrectangle Ġas Ġthe Ġinitial Ġbest Ġcandidate ĠRect . ĊĠĠĠ Ġvar Ġbest Candidate Ġ= Ġwhen Ġ( direction ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLeft Ġ-> Ġfocus Rect . translate ( focus Rect . width Ġ+ Ġ 1 , Ġ 0 f ) ĊĠĠĠĠĠĠĠ ĠRight Ġ-> Ġfocus Rect . translate (- ( focus Rect . width Ġ+ Ġ 1 ), Ġ 0 f ) ĊĠĠĠĠĠĠĠ ĠUp Ġ-> Ġfocus Rect . translate ( 0 f , Ġfocus Rect . height Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠ ĠDown Ġ-> Ġfocus Rect . translate ( 0 f , Ġ-( focus Rect . height Ġ+ Ġ 1 )) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror ( Invalid Focus Direction ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġvar Ġsearch Result : ĠFocus Modifier ? Ġ= Ġnull ĊĠĠĠ ĠforEach Ġ{ Ġcandidate Node Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġcandidate Rect Ġ= Ġcandidate Node . focus Rect () ĊĠĠĠĠĠĠĠ Ġif Ġ( is Better Candidate ( candidate Rect , Ġbest Candidate , Ġfocus Rect , Ġdirection )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbest Candidate Ġ= Ġcandidate Rect ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsearch Result Ġ= Ġcandidate Node ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġsearch Result Ċ } Ċ Ċ // ĠIs Ġthis ĠRect Ġa Ġbetter Ġcandidate Ġthan Ġcurrent Candidate Rect Ġfor Ġa Ġfocus Ġsearch Ġin Ġa Ġparticular Ċ // Ġdirection Ġfrom Ġa Ġsource Ġrect ? ĠThis Ġis Ġthe Ġcore Ġroutine Ġthat Ġdetermines Ġthe Ġorder Ġof Ġfocus Ċ // Ġsearching . Ċ private Ġfun Ġis Better Candidate ( ĊĠĠĠ Ġproposed Candidate : ĠRect , ĊĠĠĠ Ġcurrent Candidate : ĠRect , ĊĠĠĠ Ġfocused Rect : ĠRect , ĊĠĠĠ Ġdirection : ĠFocus Direction Ċ ): ĠBoolean Ġ{ ĊĊĠĠĠ Ġ// ĠIs Ġthis ĠRect Ġa Ġcandidate Ġfor Ġthe Ġnext Ġfocus Ġgiven Ġthe Ġdirection ? ĠThis Ġchecks Ġwhether Ġthe ĊĠĠĠ Ġ// Ġrect Ġis Ġat Ġleast Ġpartially Ġto Ġthe Ġdirection Ġof Ġ( e . g Ġleft Ġof ) Ġfrom Ġsource . ĠIncludes Ġan Ġedge ĊĠĠĠ Ġ// Ġcase Ġfor Ġan Ġempty Ġrect Ġ( which Ġis Ġused Ġin Ġsome Ġcases Ġwhen Ġsearching Ġfrom Ġa Ġpoint Ġon Ġthe ĊĠĠĠ Ġ// Ġscreen ). ĊĠĠĠ Ġfun ĠRect . is Candidate () Ġ= Ġwhen Ġ( direction ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLeft Ġ-> Ġ( focused Rect . right Ġ> Ġright Ġ|| Ġfocused Rect . left Ġ>= Ġright ) Ġ&& Ġfocused Rect . left Ġ> Ġleft ĊĠĠĠĠĠĠĠ ĠRight Ġ-> Ġ( focused Rect . left Ġ< Ġleft Ġ|| Ġfocused Rect . right Ġ<= Ġleft ) Ġ&& Ġfocused Rect . right Ġ< Ġright ĊĠĠĠĠĠĠĠ ĠUp Ġ-> Ġ( focused Rect . bottom Ġ> Ġbottom Ġ|| Ġfocused Rect . top Ġ>= Ġbottom ) Ġ&& Ġfocused Rect . top Ġ> Ġtop ĊĠĠĠĠĠĠĠ ĠDown Ġ-> Ġ( focused Rect . top Ġ< Ġtop Ġ|| Ġfocused Rect . bottom Ġ<= Ġtop ) Ġ&& Ġfocused Rect . bottom Ġ< Ġbottom ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror ( Invalid Focus Direction ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠThe Ġdistance Ġfrom Ġthe Ġedge Ġf ur the st Ġin Ġthe Ġgiven Ġdirection Ġof Ġsource Ġto Ġthe Ġedge Ġnearest ĊĠĠĠ Ġ// Ġin Ġthe Ġgiven Ġdirection Ġof Ġdest . ĠIf Ġthe Ġdest Ġis Ġnot Ġin Ġthe Ġdirection Ġfrom Ġsource , Ġreturn Ġ 0 . ĊĠĠĠ Ġfun ĠRect . major Axis Distance (): ĠFloat Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmajor Axis Distance Ġ= Ġwhen Ġ( direction ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLeft Ġ-> Ġfocused Rect . left Ġ- Ġright ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRight Ġ-> Ġleft Ġ- Ġfocused Rect . right ĊĠĠĠĠĠĠĠĠĠĠĠ ĠUp Ġ-> Ġfocused Rect . top Ġ- Ġbottom ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown Ġ-> Ġtop Ġ- Ġfocused Rect . bottom ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror ( Invalid Focus Direction ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġmax ( 0 . 0 f , Ġmajor Axis Distance ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠFind Ġthe Ġdistance Ġon Ġthe Ġminor Ġaxis Ġw . r . t Ġthe Ġdirection Ġto Ġthe Ġnearest Ġedge Ġof Ġthe ĊĠĠĠ Ġ// Ġdestination Ġrectangle . ĊĠĠĠ Ġfun ĠRect . minor Axis Distance () Ġ= Ġwhen Ġ( direction ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġthe Ġdistance Ġbetween Ġthe Ġcenter Ġvertical s ĊĠĠĠĠĠĠĠ ĠLeft , ĠRight Ġ-> Ġ( focused Rect . top Ġ+ Ġfocused Rect . height Ġ/ Ġ 2 ) Ġ- Ġ( top Ġ+ Ġheight Ġ/ Ġ 2 ) ĊĠĠĠĠĠĠĠ Ġ// Ġthe Ġdistance Ġbetween Ġthe Ġcenter Ġh orizont als ĊĠĠĠĠĠĠĠ ĠUp , ĠDown Ġ-> Ġ( focused Rect . left Ġ+ Ġfocused Rect . width Ġ/ Ġ 2 ) Ġ- Ġ( left Ġ+ Ġwidth Ġ/ Ġ 2 ) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror ( Invalid Focus Direction ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠF udge - factor Ġopportunity : Ġhow Ġto Ġcalculate Ġdistance Ġgiven Ġmajor Ġand Ġminor Ġaxis Ġdistances . ĊĠĠĠ Ġ// ĠWarning : ĠThis Ġf udge Ġfactor Ġis Ġfin ely Ġt uned , Ġrun Ġall Ġfocus Ġtests Ġif Ġyou Ġd are Ġtweak Ġit . ĊĠĠĠ Ġfun Ġweighted Distance ( candidate : ĠRect ): ĠLong Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmajor Axis Distance Ġ= Ġcandidate . major Axis Distance (). absolute Value . to Long () ĊĠĠĠĠĠĠĠ Ġval Ġminor Axis Distance Ġ= Ġcandidate . minor Axis Distance (). absolute Value . to Long () ĊĠĠĠĠĠĠĠ Ġreturn Ġ 1 3 Ġ* Ġmajor Axis Distance Ġ* Ġmajor Axis Distance Ġ+ Ġminor Axis Distance Ġ* Ġminor Axis Distance ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġto Ġbe Ġa Ġbetter Ġcandidate , Ġneed Ġto Ġat Ġleast Ġbe Ġa Ġcandidate Ġin Ġthe Ġfirst Ġplace . ĊĠĠĠĠĠĠĠ Ġ! pro posed Candidate . is Candidate () Ġ-> Ġfalse ĊĊĠĠĠĠĠĠĠ Ġ// ĠIf Ġthe Ġcurrent Candidate Ġis Ġnot Ġa Ġcandidate , Ġproposed Candidate Ġis Ġbetter . ĊĠĠĠĠĠĠĠ Ġ! current Candidate . is Candidate () Ġ-> Ġtrue ĊĊĠĠĠĠĠĠĠ Ġ// Ġif Ġproposed Candidate Ġis Ġbetter Ġby Ġbeam , Ġit Ġwins . ĊĠĠĠĠĠĠĠ Ġbeam Be ats ( focused Rect , Ġproposed Candidate , Ġcurrent Candidate , Ġdirection ) Ġ-> Ġtrue ĊĊĠĠĠĠĠĠĠ Ġ// Ġif Ġcurrent Candidate Ġis Ġbetter , Ġthen Ġthe Ġproposed Candidate Ġcan 't Ġbe . ĊĠĠĠĠĠĠĠ Ġbeam Be ats ( focused Rect , Ġcurrent Candidate , Ġproposed Candidate , Ġdirection ) Ġ-> Ġfalse ĊĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġweighted Distance ( pro posed Candidate ) Ġ< Ġweighted Distance ( current Candidate ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠA Ġrectangle Ġmay Ġbe Ġa Ġbetter Ġcandidate Ġby Ġvirtue Ġof Ġbeing Ġexclus ively Ġin Ġthe Ġbeam Ġof Ġthe Ġsource Ċ Ġ* Ġrect . Ċ Ġ* Ġ@ return ĠWhether Ġrect 1 Ġis Ġa Ġbetter Ġcandidate Ġthan Ġrect 2 Ġby Ġvirtue Ġof Ġit Ġbeing Ġin Ġthe Ġsource 's Ċ Ġ* Ġbeam . Ċ Ġ*/ Ċ private Ġfun Ġbeam Be ats ( ĊĠĠĠ Ġsource : ĠRect , ĊĠĠĠ Ġrect 1 : ĠRect , ĊĠĠĠ Ġrect 2 : ĠRect , ĊĠĠĠ Ġdirection : ĠFocus Direction Ċ ): ĠBoolean Ġ{ ĊĠĠĠ Ġ// ĠDo Ġthe Ġ" be ams " Ġw . r . t Ġthe Ġgiven Ġdirection 's Ġaxis Ġof Ġrect 1 Ġand Ġrect 2 Ġoverlap ? ĊĠĠĠ Ġfun ĠRect . in Source Beam () Ġ= Ġwhen Ġ( direction ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLeft , ĠRight Ġ-> Ġthis . bottom Ġ> Ġsource . top Ġ&& Ġthis . top Ġ< Ġsource . bottom ĊĠĠĠĠĠĠĠ ĠUp , ĠDown Ġ-> Ġthis . right Ġ> Ġsource . left Ġ&& Ġthis . left Ġ< Ġsource . right ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror ( Invalid Focus Direction ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠWhether Ġthe Ġrect Ġis Ġin Ġthe Ġdirection Ġof Ġsearch . ĊĠĠĠ Ġfun ĠRect . isIn Direction Of Search () Ġ= Ġwhen Ġ( direction ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLeft Ġ-> Ġsource . left Ġ>= Ġright ĊĠĠĠĠĠĠĠ ĠRight Ġ-> Ġsource . right Ġ<= Ġleft ĊĠĠĠĠĠĠĠ ĠUp Ġ-> Ġsource . top Ġ>= Ġbottom ĊĠĠĠĠĠĠĠ ĠDown Ġ-> Ġsource . bottom Ġ<= Ġtop ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror ( Invalid Focus Direction ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠThe Ġdistance Ġfrom Ġthe Ġedge Ġf ur the st Ġin Ġthe Ġgiven Ġdirection Ġof Ġsource Ġto Ġthe Ġedge Ġnearest ĊĠĠĠ Ġ// Ġin Ġthe Ġgiven Ġdirection Ġof Ġdest . ĠIf Ġthe Ġdest Ġis Ġnot Ġin Ġthe Ġdirection Ġfrom Ġsource , Ġreturn Ġ 0 . ĊĠĠĠ Ġfun ĠRect . major Axis Distance (): ĠFloat Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmajor Axis Distance Ġ= Ġwhen Ġ( direction ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLeft Ġ-> Ġsource . left Ġ- Ġright ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRight Ġ-> Ġleft Ġ- Ġsource . right ĊĠĠĠĠĠĠĠĠĠĠĠ ĠUp Ġ-> Ġsource . top Ġ- Ġbottom ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown Ġ-> Ġtop Ġ- Ġsource . bottom ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror ( Invalid Focus Direction ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġmax ( 0 . 0 f , Ġmajor Axis Distance ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠThe Ġdistance Ġalong Ġthe Ġmajor Ġaxis Ġw . r . t Ġthe Ġdirection Ġfrom Ġthe Ġedge Ġof Ġsource Ġto Ġthe Ġfar ĊĠĠĠ Ġ// Ġedge Ġof Ġdest . ĠIf Ġthe Ġdest Ġis Ġnot Ġin Ġthe Ġdirection Ġfrom Ġsource , Ġreturn Ġ 1 Ġ( to Ġbreak Ġt ies ĊĠĠĠ Ġ// Ġwith ĠRect . major Axis Distance ). ĊĠĠĠ Ġfun ĠRect . major Axis Distance To Far Edge (): ĠFloat Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmajor Axis Distance Ġ= Ġwhen Ġ( direction ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLeft Ġ-> Ġsource . left Ġ- Ġleft ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRight Ġ-> Ġright Ġ- Ġsource . right ĊĠĠĠĠĠĠĠĠĠĠĠ ĠUp Ġ-> Ġsource . top Ġ- Ġtop ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown Ġ-> Ġbottom Ġ- Ġsource . bottom ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror ( Invalid Focus Direction ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġmax ( 1 . 0 f , Ġmajor Axis Distance ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġif Ġrect 1 Ġisn 't Ġexclus ively Ġin Ġthe Ġsrc Ġbeam , Ġit Ġdoesn 't Ġwin ĊĠĠĠĠĠĠĠ Ġrect 2 . in Source Beam () Ġ|| Ġ! rect 1 . in Source Beam () Ġ-> Ġfalse ĊĊĠĠĠĠĠĠĠ Ġ// ĠWe Ġknow Ġrect 1 Ġis Ġin Ġthe Ġbeam , Ġand Ġrect 2 Ġis Ġnot . ĠIf ĠRect 2 Ġis Ġnot Ġin Ġthe Ġdirection Ġof ĊĠĠĠĠĠĠĠ Ġ// Ġsearch , Ġrect 1 Ġwins Ġ( since Ġrect 2 Ġcould Ġbe Ġreached Ġby Ġgoing Ġin Ġanother Ġdirection ). ĊĠĠĠĠĠĠĠ Ġ! rect 2 . isIn Direction Of Search () Ġ-> Ġtrue ĊĊĠĠĠĠĠĠĠ Ġ// Ġfor Ġhorizontal Ġdirections , Ġbeing Ġexclus ively Ġin Ġbeam Ġalways Ġwins ĊĠĠĠĠĠĠĠ Ġdirection Ġ== ĠLeft Ġ|| Ġdirection Ġ== ĠRight Ġ-> Ġtrue ĊĊĠĠĠĠĠĠĠ Ġ// Ġfor Ġvertical Ġdirections , Ġbe ams Ġonly Ġbeat Ġup Ġto Ġa Ġpoint : ĊĠĠĠĠĠĠĠ Ġ// Ġnow , Ġas Ġlong Ġas Ġrect 2 Ġisn 't Ġcompletely Ġcloser , Ġrect 1 Ġwins ĊĠĠĠĠĠĠĠ Ġ// Ġe . g Ġfor Ġdirection Ġdown , Ġcompletely Ġcloser Ġmeans Ġfor Ġrect 2 's Ġtop ĊĠĠĠĠĠĠĠ Ġ// Ġedge Ġto Ġbe Ġcloser Ġto Ġthe Ġsource 's Ġtop Ġedge Ġthan Ġrect 1 's Ġbottom Ġedge . ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġrect 1 . major Axis Distance () Ġ< Ġrect 2 . major Axis Distance To Far Edge () ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠRect . top Left () Ġ= ĠRect ( left , Ġtop , Ġleft , Ġtop ) Ċ private Ġfun ĠRect . bottom Right () Ġ= ĠRect ( right , Ġbottom , Ġright , Ġbottom ) Ċ Ċ // ĠFind Ġthe Ġactive Ġdesc endant . Ċ @ Suppress (" Modifier Factory Extension Function ", Ġ" Modifier Factory ReturnType ") Ċ private Ġfun ĠFocus Modifier . active Node (): ĠFocus Modifier Ġ{ ĊĠĠĠ Ġcheck ( focus State Ġ== ĠActive Parent Ġ|| Ġfocus State Ġ== ĠDe activated Parent ) ĊĠĠĠ Ġreturn Ġfind Active Focus Node () Ġ?: Ġerror ( No Active Child ) Ċ } Ċ