/* Ċ Ġ* ĠCopyright Ġ 2 0 2 0 Ġ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 . runtime . collection . mutable Vector Of Ċ import Ġandroidx . compose . ui . Experimental Compose Ui Api Ċ import Ġandroidx . compose . ui . focus . Focus Direction . Companion . Down Ċ import Ġandroidx . compose . ui . focus . Focus Direction . Companion . In Ċ import Ġandroidx . compose . ui . focus . Focus Direction . Companion . Left Ċ import Ġandroidx . compose . ui . focus . Focus Direction . Companion . Next Ċ import Ġandroidx . compose . ui . focus . Focus Direction . Companion . Out Ċ import Ġandroidx . compose . ui . focus . Focus Direction . Companion . Previous Ċ 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 Ġandroidx . compose . ui . input . key . Key Input Modifier Ċ import Ġandroidx . compose . ui . layout . find Root Ċ import Ġandroidx . compose . ui . unit . Layout Direction Ċ import Ġandroidx . compose . ui . unit . Layout Direction . L tr Ċ import Ġandroidx . compose . ui . unit . Layout Direction . R tl Ċ Ċ private Ġconst Ġval Ġinvalid Focus Direction Ġ= Ġ" Invalid ĠFocus Direction " Ċ Ċ /** Ċ Ġ* ĠThe Ġ[ Focus Direction ] Ġis Ġused Ġto Ġspecify Ġthe Ġdirection Ġfor Ġa Ġ[ Focus Manager . move Focus ] Ċ Ġ* Ġrequest . Ċ Ġ* Ċ Ġ* Ġ@ sample Ġandroidx . compose . ui . samples . Move Focus Sample Ċ Ġ*/ Ċ @ kotlin . jvm . Jvm Inline Ċ value Ġclass ĠFocus Direction Ġinternal Ġconstructor (@ Suppress (" unused ") Ġprivate Ġval Ġvalue : ĠInt ) Ġ{ ĊĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( this ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNext Ġ-> Ġ" Next " ĊĠĠĠĠĠĠĠĠĠĠĠ ĠPrevious Ġ-> Ġ" Previous " ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLeft Ġ-> Ġ" Left " ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRight Ġ-> Ġ" Right " ĊĠĠĠĠĠĠĠĠĠĠĠ ĠUp Ġ-> Ġ" Up " ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDown Ġ-> Ġ" Down " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Opt In ( Experimental Compose Ui Api :: class ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠIn Ġ-> Ġ" In " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Opt In ( Experimental Compose Ui Api :: class ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOut Ġ-> Ġ" Out " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġinvalid Focus Direction ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* Ġ ĠDirection Ġused Ġin Ġ[ Focus Manager . move Focus ] Ġto Ġindicate Ġthat Ġyou Ġare Ġsearching Ġfor Ġthe ĊĠĠĠĠĠĠĠĠ Ġ* Ġ Ġnext Ġfocus able Ġitem . ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ Ġ@ sample Ġandroidx . compose . ui . samples . Move Focus Sample ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġval ĠNext : ĠFocus Direction Ġ= ĠFocus Direction ( 1 ) ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* Ġ ĠDirection Ġused Ġin Ġ[ Focus Manager . move Focus ] Ġto Ġindicate Ġthat Ġyou Ġare Ġsearching Ġfor Ġthe ĊĠĠĠĠĠĠĠĠ Ġ* Ġ Ġprevious Ġfocus able Ġitem . ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ Ġ@ sample Ġandroidx . compose . ui . samples . Move Focus Sample ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġval ĠPrevious : ĠFocus Direction Ġ= ĠFocus Direction ( 2 ) ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* Ġ ĠDirection Ġused Ġin Ġ[ Focus Manager . move Focus ] Ġto Ġindicate Ġthat Ġyou Ġare Ġsearching Ġfor Ġthe ĊĠĠĠĠĠĠĠĠ Ġ* Ġ Ġnext Ġfocus able Ġitem Ġto Ġthe Ġleft Ġof Ġthe Ġcurrently Ġfocused Ġitem . ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ Ġ@ sample Ġandroidx . compose . ui . samples . Move Focus Sample ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġval ĠLeft : ĠFocus Direction Ġ= ĠFocus Direction ( 3 ) ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* Ġ ĠDirection Ġused Ġin Ġ[ Focus Manager . move Focus ] Ġto Ġindicate Ġthat Ġyou Ġare Ġsearching Ġfor Ġthe ĊĠĠĠĠĠĠĠĠ Ġ* Ġ Ġnext Ġfocus able Ġitem Ġto Ġthe Ġright Ġof Ġthe Ġcurrently Ġfocused Ġitem . ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ Ġ@ sample Ġandroidx . compose . ui . samples . Move Focus Sample ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġval ĠRight : ĠFocus Direction Ġ= ĠFocus Direction ( 4 ) ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* Ġ ĠDirection Ġused Ġin Ġ[ Focus Manager . move Focus ] Ġto Ġindicate Ġthat Ġyou Ġare Ġsearching Ġfor Ġthe ĊĠĠĠĠĠĠĠĠ Ġ* Ġ Ġnext Ġfocus able Ġitem Ġthat Ġis Ġabove Ġthe Ġcurrently Ġfocused Ġitem . ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ Ġ@ sample Ġandroidx . compose . ui . samples . Move Focus Sample ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġval ĠUp : ĠFocus Direction Ġ= ĠFocus Direction ( 5 ) ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* Ġ ĠDirection Ġused Ġin Ġ[ Focus Manager . move Focus ] Ġto Ġindicate Ġthat Ġyou Ġare Ġsearching Ġfor Ġthe ĊĠĠĠĠĠĠĠĠ Ġ* Ġ Ġnext Ġfocus able Ġitem Ġthat Ġis Ġbelow Ġthe Ġcurrently Ġfocused Ġitem . ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ Ġ@ sample Ġandroidx . compose . ui . samples . Move Focus Sample ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġval ĠDown : ĠFocus Direction Ġ= ĠFocus Direction ( 6 ) ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* Ġ ĠDirection Ġused Ġin Ġ[ Focus Manager . move Focus ] Ġto Ġindicate Ġthat Ġyou Ġare Ġsearching Ġfor Ġthe ĊĠĠĠĠĠĠĠĠ Ġ* Ġ Ġnext Ġfocus able Ġitem Ġthat Ġis Ġa Ġchild Ġof Ġthe Ġcurrently Ġfocused Ġitem . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ@ Experimental Compose Ui Api ĊĠĠĠĠĠĠĠ Ġval ĠIn : ĠFocus Direction Ġ= ĠFocus Direction ( 7 ) ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* Ġ ĠDirection Ġused Ġin Ġ[ Focus Manager . move Focus ] Ġto Ġindicate Ġthat Ġyou Ġwant Ġto Ġmove Ġfocus Ġto ĊĠĠĠĠĠĠĠĠ Ġ* Ġ Ġthe Ġparent Ġof Ġthe Ġcurrently Ġfocused Ġitem . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ@ Experimental Compose Ui Api ĊĠĠĠĠĠĠĠ Ġval ĠOut : ĠFocus Direction Ġ= ĠFocus Direction ( 8 ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠMov es Ġfocus Ġbased Ġon Ġthe Ġrequested Ġfocus Ġdirection . Ċ Ġ* Ċ Ġ* Ġ@ param Ġfocus Direction ĠThe Ġrequested Ġdirection Ġto Ġmove Ġfocus . Ċ Ġ* Ġ@ param Ġlayout Direction ĠWhether Ġthe Ġlayout Ġis ĠRTL Ġor ĠL TR . Ċ Ġ* Ġ@ param Ġon Found ĠThis Ġlambda Ġis Ġinvoked Ġif Ġfocus Ġsearch Ġfinds Ġthe Ġnext Ġfocus Ġnode . Ċ Ġ* Ġ@ return Ġif Ġno Ġfocus Ġnode Ġis Ġfound , Ġwe Ġreturn Ġfalse . Ġotherwise Ġwe Ġreturn Ġthe Ġresult Ġof Ġ[ on Found ]. Ċ Ġ*/ Ċ internal Ġfun ĠFocus Modifier . focus Search ( ĊĠĠĠ Ġfocus Direction : ĠFocus Direction , ĊĠĠĠ Ġlayout Direction : ĠLayout Direction , ĊĠĠĠ Ġon Found : Ġ( Focus Modifier ) Ġ-> ĠBoolean Ċ ): ĠBoolean Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ( focus Direction ) Ġ{ ĊĠĠĠĠĠĠĠ ĠNext , ĠPrevious Ġ-> Ġone Dimension al Focus Search ( focus Direction , Ġon Found ) ĊĠĠĠĠĠĠĠ ĠLeft , ĠRight , ĠUp , ĠDown Ġ-> Ġtwo Dimension al Focus Search ( focus Direction , Ġon Found ) ĊĠĠĠĠĠĠĠ Ġ@ Opt In ( Experimental Compose Ui Api :: class ) ĊĠĠĠĠĠĠĠ ĠIn Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġsearch Ġamong Ġthe Ġchildren Ġof Ġthe Ġactive Ġitem . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdirection Ġ= Ġwhen Ġ( layout Direction ) Ġ{ ĠR tl Ġ-> ĠLeft ; ĠL tr Ġ-> ĠRight Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfind Active Focus Node ()?. two Dimension al Focus Search ( direction , Ġon Found ) Ġ?: Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ@ Opt In ( Experimental Compose Ui Api :: class ) ĊĠĠĠĠĠĠĠ ĠOut Ġ-> Ġfind Active Focus Node ()?. find Active Parent (). let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it Ġ== Ġthis Ġ|| Ġit Ġ== Ġnull ) Ġfalse Ġelse Ġon Found . invoke ( it ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror ( invalid Focus Direction ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ @ Suppress (" Modifier Factory Extension Function ", Ġ" Modifier Factory ReturnType ") Ċ internal Ġfun ĠFocus Modifier . find Active Focus Node (): ĠFocus Modifier ? Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ( focus State ) Ġ{ ĊĠĠĠĠĠĠĠ ĠActive , ĠCapt ured Ġ-> Ġthis ĊĠĠĠĠĠĠĠ ĠActive Parent , ĠDe activated Parent Ġ-> Ġfocused Child ?. find Active Focus Node () ĊĠĠĠĠĠĠĠ ĠIn active , ĠDe activated Ġ-> Ġnull ĊĠĠĠ Ġ} Ċ } Ċ Ċ @ Suppress (" Modifier Factory Extension Function ", Ġ" Modifier Factory ReturnType ") Ċ internal Ġfun ĠFocus Modifier . find Active Parent (): ĠFocus Modifier ? Ġ= Ġparent ?. let Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( focus State ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠActive , ĠCapt ured , ĠDe activated , ĠDe activated Parent , ĠIn active Ġ-> Ġit . find Active Parent () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠActive Parent Ġ-> Ġthis ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ /** Ċ Ġ* ĠReturns Ġthe Ġbounding Ġbox Ġof Ġthe Ġfocus Ġlayout Ġarea Ġin Ġthe Ġroot Ġor Ġ[ Rect . Zero ] Ġif Ġthe Ċ Ġ* ĠFocus Modifier Ġhas Ġnot Ġhad Ġa Ġlayout . Ċ Ġ*/ Ċ internal Ġfun ĠFocus Modifier . focus Rect (): ĠRect Ġ= Ġlayout Node Wrapper ?. let Ġ{ ĊĠĠĠ Ġit . find Root (). local BoundingBox Of ( it , Ġclip Bounds Ġ= Ġfalse ) Ċ } Ġ?: ĠRect . Zero Ċ Ċ /** Ċ Ġ* ĠReturns Ġall Ġ[ Focus Modifier ] Ġchildren Ġthat Ġare Ġnot Ġ[ Focus State Impl . is De activated ]. ĠAny Ċ Ġ* Ġchild Ġthat Ġis Ġde activated Ġwill Ġadd Ġactivated Ġchildren Ġinstead . Ċ Ġ*/ Ċ internal Ġfun ĠFocus Modifier . activated Children (): ĠMutable Vector < Focus Modifier > Ġ{ ĊĠĠĠ Ġif Ġ(! children . any Ġ{ Ġit . focus State . is De activated Ġ}) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġchildren ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġactivated Ġ= Ġmutable Vector Of < Focus Modifier >() ĊĠĠĠ Ġchildren . forEach Ġ{ Ġchild Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ(! child . focus State . is De activated ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġactivated Ġ+= Ġchild ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġactivated . addAll ( child . activated Children ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġactivated Ċ } Ċ Ċ /** Ċ Ġ* ĠReturns Ġthe Ġinner - most ĠKey Input Modifier Ġon Ġthe Ġsame ĠLayout Node Ġas Ġthis ĠFocus Modifier . Ċ Ġ*/ Ċ @ Suppress (" Modifier Factory Extension Function ", Ġ" Modifier Factory ReturnType ") Ċ internal Ġfun ĠFocus Modifier . find Last Key Input Modifier (): ĠKey Input Modifier ? Ġ{ ĊĠĠĠ Ġval Ġlayout Node Ġ= Ġlayout Node Wrapper ?. layout Node Ġ?: Ġreturn Ġnull ĊĠĠĠ Ġvar Ġbest : ĠKey Input Modifier ? Ġ= Ġnull ĊĠĠĠ Ġkey Input Children . forEach Ġ{ Ġkey Input Modifier Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ( key Input Modifier . layout Node Ġ== Ġlayout Node ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbest Ġ= Ġlast Of ( key Input Modifier , Ġbest ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġif Ġ( best Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġbest ĊĠĠĠ Ġ} ĊĠĠĠ Ġ// ĠThere Ġisn 't Ġa ĠKey Input Modifier Ġafter Ġthis , Ġbut Ġthere Ġmay Ġbe Ġone Ġbefore Ġthis . ĊĠĠĠ Ġreturn Ġkey Input Modifier Ċ } Ċ Ċ /** Ċ Ġ* ĠWhether Ġthis Ġnode Ġshould Ġbe Ġconsidered Ġwhen Ġsearching Ġfor Ġthe Ġnext Ġitem Ġduring Ġa Ġtraversal . Ċ Ġ*/ Ċ internal Ġval ĠFocus Modifier . is El igible For Focus Search : ĠBoolean ĊĠĠĠ Ġget () Ġ= Ġlayout Node Wrapper ?. layout Node ?. is Pl aced Ġ== Ġtrue Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlayout Node Wrapper ?. layout Node ?. is Attached Ġ== Ġtrue Ċ Ċ /** Ċ Ġ* ĠReturns Ġ[ one ] Ġif Ġit Ġcomes Ġafter Ġ[ two ] Ġin Ġthe Ġmodifier Ġchain Ġor Ġ[ two ] Ġif Ġit Ġcomes Ġafter Ġ[ one ]. Ċ Ġ*/ Ċ @ Suppress (" Modifier Factory Extension Function ", Ġ" Modifier Factory ReturnType ") Ċ private Ġfun Ġlast Of ( one : ĠKey Input Modifier , Ġtwo : ĠKey Input Modifier ?): ĠKey Input Modifier Ġ{ ĊĠĠĠ Ġvar Ġmod Ġ= Ġtwo Ġ?: Ġreturn Ġone ĊĠĠĠ Ġval Ġlayout Node Ġ= Ġone . layout Node ĊĠĠĠ Ġwhile Ġ( mod Ġ!= Ġone ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġparent Ġ= Ġmod . parent ĊĠĠĠĠĠĠĠ Ġif Ġ( parent Ġ== Ġnull Ġ|| Ġparent . layout Node Ġ!= Ġlayout Node ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġone ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġmod Ġ= Ġparent ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġtwo Ċ }