package Ġmy . nan ih ades uka . compose Ċ Ċ import Ġandroidx . compose . animation . core . animate Float As State Ċ import Ġandroidx . compose . animation . core . t ween Ċ import Ġandroidx . compose . foundation . background Ċ import Ġandroidx . compose . foundation . gest ures . Orientation Ċ import Ġandroidx . compose . foundation . gest ures . draggable Ċ import Ġandroidx . compose . foundation . gest ures . remember Drag gable State Ċ import Ġandroidx . compose . foundation . layout .* Ċ import Ġandroidx . compose . foundation . lazy . Lazy List State Ċ import Ġandroidx . compose . foundation . shape . Circle Shape Ċ import Ġandroidx . compose . runtime .* Ċ import Ġandroidx . compose . ui . Alignment Ċ import Ġandroidx . compose . ui . Modifier Ċ import Ġandroidx . compose . ui . draw . alpha Ċ import Ġandroidx . compose . ui . draw . clip Ċ import Ġandroidx . compose . ui . graphics . Color Ċ import Ġandroidx . compose . ui . graphics . Shape Ċ import Ġandroidx . compose . ui . graphics . graphics Layer Ċ import Ġandroidx . compose . ui . unit . Dp Ċ import Ġandroidx . compose . ui . unit . dp Ċ import Ġkotlinx . coroutines . launch Ċ import Ġkotlin . math . floor Ċ Ċ /** Ċ Ġ* ĠScroll bar Ġfor ĠLazy Column Ċ Ġ* Ċ Ġ* Ġ@ param Ġright Side Ġtrue Ġ-> Ġright , Ġ Ġfalse Ġ-> Ġleft Ċ Ġ* Ġ@ param Ġthickness ĠTh ickness Ġof Ġthe Ġscrollbar Ġthumb Ċ Ġ* Ġ@ param Ġpadding ĠĠ ĠPadding Ġof Ġthe Ġscrollbar Ċ Ġ* Ġ@ param Ġthumb Min Height ĠThumb Ġminimum Ġheight Ġpro portional Ġto Ġtotal Ġscrollbar 's Ġheight Ġ( eg : Ġ 0 . 1 Ġ-> Ġ 1 0 % Ġof Ġtotal ) Ċ Ġ*/ Ċ @ Composable Ċ fun ĠLazy Column Scrollbar ( Ċ ĉ list State : ĠLazy List State , Ċ ĉ right Side : ĠBoolean Ġ= Ġtrue , Ċ ĉ thickness : ĠD p Ġ= Ġ 6 . dp , Ċ ĉ padding : ĠD p Ġ= Ġ 8 . dp , Ċ ĉ thumb Min Height : ĠFloat Ġ= Ġ 0 . 1 f , Ċ ĉ thumb Color : ĠColor Ġ= ĠColor ( 0 xFF 2 A 5 9 B 6 ), Ċ ĉ thumb Selected Color : ĠColor Ġ= ĠColor ( 0 xFF 5 2 8 1 CA ), Ċ ĉ thumb Shape : ĠShape Ġ= ĠCircle Shape , Ċ ĉ content : Ġ@ Composable Ġ() Ġ-> ĠUnit Ċ ) Ċ { Ċ ĉ Box Ġ{ Ċĉ ĉ content () Ċĉ ĉ Lazy Column Scrollbar ( Ċĉĉ ĉ list State Ġ= Ġlist State , Ċĉĉ ĉ right Side Ġ= Ġright Side , Ċĉĉ ĉ thickness Ġ= Ġthickness , Ċĉĉ ĉ padding Ġ= Ġpadding , Ċĉĉ ĉ thumb Min Height Ġ= Ġthumb Min Height , Ċĉĉ ĉ thumb Color Ġ= Ġthumb Color , Ċĉĉ ĉ thumb Selected Color Ġ= Ġthumb Selected Color , Ċĉĉ ĉ thumb Shape Ġ= Ġthumb Shape , Ċĉ ĉ ) Ċ ĉ } Ċ } Ċ Ċ /** Ċ Ġ* ĠScroll bar Ġfor ĠLazy Column Ċ Ġ* Ċ Ġ* Ġ@ param Ġright Side Ġtrue Ġ-> Ġright , Ġ Ġfalse Ġ-> Ġleft Ċ Ġ* Ġ@ param Ġthickness ĠTh ickness Ġof Ġthe Ġscrollbar Ġthumb Ċ Ġ* Ġ@ param Ġpadding ĠĠ ĠPadding Ġof Ġthe Ġscrollbar Ċ Ġ* Ġ@ param Ġthumb Min Height ĠThumb Ġminimum Ġheight Ġpro portional Ġto Ġtotal Ġscrollbar 's Ġheight Ġ( eg : Ġ 0 . 1 Ġ-> Ġ 1 0 % Ġof Ġtotal ) Ċ Ġ*/ Ċ @ Composable Ċ fun ĠLazy Column Scrollbar ( Ċ ĉ list State : ĠLazy List State , Ċ ĉ right Side : ĠBoolean Ġ= Ġtrue , Ċ ĉ thickness : ĠD p Ġ= Ġ 6 . dp , Ċ ĉ padding : ĠD p Ġ= Ġ 8 . dp , Ċ ĉ thumb Min Height : ĠFloat Ġ= Ġ 0 . 1 f , Ċ ĉ thumb Color : ĠColor Ġ= ĠColor ( 0 xFF 2 A 5 9 B 6 ), Ċ ĉ thumb Selected Color : ĠColor Ġ= ĠColor ( 0 xFF 5 2 8 1 CA ), Ċ ĉ thumb Shape : ĠShape Ġ= ĠCircle Shape Ċ ) Ċ { Ċ ĉ val Ġcoroutine Scope Ġ= Ġremember Coroutine Scope () ĊĉĊ ĉ var Ġis Selected Ġby Ġremember Ġ{ Ġmutable State Of ( false ) Ġ} ĊĉĊ ĉ var Ġdrag Offset Ġby Ġremember Ġ{ Ġmutable State Of ( 0 f ) Ġ} ĊĉĊ ĉ fun Ġnormalized Thumb Size () Ġ= Ġlist State . layout Info . let Ġ{ Ċĉ ĉ if Ġ( it . total Items Count Ġ== Ġ 0 ) Ġreturn @ let Ġ 0 f Ċĉ ĉ val Ġfirst Partial Ġ= Ġit . visible Items Info . first (). run Ġ{ Ġ- offset . toFloat () Ġ/ Ġsize . toFloat () Ġ} Ċĉ ĉ val Ġlast Partial Ġ= Ġit . visible Items Info . last (). run Ġ{ Ġ 1 f Ġ- Ġ( it . viewport End Offset Ġ- Ġoffset ). toFloat () Ġ/ Ġsize . toFloat () Ġ} Ċĉ ĉ val Ġreal Visible Size Ġ= Ġit . visible Items Info . size . toFloat () Ġ- Ġfirst Partial Ġ- Ġlast Partial Ċĉ ĉ real Visible Size Ġ/ Ġit . total Items Count . toFloat () Ċ ĉ }. coerce At Least ( thumb Min Height ) ĊĉĊ ĉ fun Ġnormalized Offset Position () Ġ= Ġlist State . layout Info . let Ġ{ Ċĉ ĉ if Ġ( it . total Items Count Ġ== Ġ 0 Ġ|| Ġit . visible Items Info . isEmpty ()) Ġ 0 f Ċĉ ĉ else Ġit . visible Items Info . first (). run Ġ{ Ġindex . toFloat () Ġ- Ġoffset . toFloat () Ġ/ Ġsize . toFloat () Ġ} Ġ/ Ġit . total Items Count . toFloat () Ċ ĉ } ĊĉĊ ĉ fun Ġset Scroll Offset ( new Offset : ĠFloat ) Ċ ĉ { Ċĉ ĉ drag Offset Ġ= Ġnew Offset . coerce In ( 0 f , Ġ 1 f ) ĊĉĉĊĉ ĉ val Ġexact Index : ĠFloat Ġ= Ġlist State . layout Info . total Items Count . toFloat () Ġ* Ġdrag Offset Ċĉ ĉ val Ġindex : ĠInt Ġ= Ġfloor ( exact Index ). toInt () Ċĉ ĉ val Ġremainder : ĠFloat Ġ= Ġexact Index Ġ- Ġfloor ( exact Index ) ĊĉĉĊĉ ĉ coroutine Scope . launch Ġ{ Ċĉĉ ĉ list State . scrollTo Item ( index Ġ= Ġindex , Ġscroll Offset Ġ= Ġ 0 ) Ċĉĉ ĉ val Ġoffset Ġ= Ġlist State . layout Info . visible Items Info . first OrNull ()?. size ?. let Ġ{ Ġit . toFloat () Ġ* Ġremainder Ġ} ?. toInt () Ġ?: Ġ 0 Ċĉĉ ĉ list State . scrollTo Item ( index Ġ= Ġindex , Ġscroll Offset Ġ= Ġoffset ) Ċĉ ĉ } Ċ ĉ } ĊĉĊ ĉ val ĠisIn Action Ġ= Ġlist State . is Scroll InProgress Ġ|| Ġis Selected ĊĉĊ ĉ val Ġalpha Ġby Ġanimate Float As State ( Ċĉ ĉ target Value Ġ= Ġif Ġ( isIn Action ) Ġ 1 f Ġelse Ġ 0 f , Ċĉ ĉ animation Spec Ġ= Ġt ween ( duration Millis Ġ= Ġif Ġ( isIn Action ) Ġ 7 5 Ġelse Ġ 5 0 0 , Ġdelay Millis Ġ= Ġif Ġ( isIn Action ) Ġ 0 Ġelse Ġ 5 0 0 ) Ċ ĉ ) ĊĉĊ ĉ val Ġdisplacement Ġby Ġanimate Float As State ( Ċĉ ĉ target Value Ġ= Ġif Ġ( isIn Action ) Ġ 0 f Ġelse Ġ 1 4 f , Ċĉ ĉ animation Spec Ġ= Ġt ween ( duration Millis Ġ= Ġif Ġ( isIn Action ) Ġ 7 5 Ġelse Ġ 5 0 0 , Ġdelay Millis Ġ= Ġif Ġ( isIn Action ) Ġ 0 Ġelse Ġ 5 0 0 ) Ċ ĉ ) ĊĉĊ ĉ Box With Constraints ( Modifier . fill Max Width ()) Ġ{ ĊĉĉĊĉ ĉ val Ġdrag State Ġ= Ġremember Drag gable State Ġ{ Ġdelta Ġ-> Ċĉĉ ĉ set Scroll Offset ( drag Offset Ġ+ Ġdelta Ġ/ Ġconstraints . max Height . toFloat ()) Ċĉ ĉ } ĊĉĉĊĉ ĉ Box With Constraints ( Ċĉĉ ĉ Modifier Ċĉĉĉ ĉ . align ( if Ġ( right Side ) ĠAlignment . Top End Ġelse ĠAlignment . Top Start ) Ċĉĉĉ ĉ . alpha ( alpha ) Ċĉĉĉ ĉ . fill Max Height () Ċĉĉĉ ĉ . draggable ( Ċĉĉĉĉ ĉ state Ġ= Ġdrag State , Ċĉĉĉĉ ĉ orientation Ġ= ĠOrientation . Vertical , Ċĉĉĉĉ ĉ start Drag Immediate ly Ġ= Ġtrue , Ċĉĉĉĉ ĉ on Drag Started Ġ= Ġ{ Ġoffset Ġ-> Ċĉĉĉĉĉ ĉ val Ġnew Offset Ġ= Ġoffset . y Ġ/ Ġconstraints . max Height . toFloat () Ċĉĉĉĉĉ ĉ val Ġcurrent Offset Ġ= Ġnormalized Offset Position () ĊĉĉĉĉĉĉĊĉĉĉĉĉ ĉ if Ġ( current Offset Ġ< Ġnew Offset Ġ&& Ġnew Offset Ġ< Ġcurrent Offset Ġ+ Ġnormalized Thumb Size ()) Ċĉĉĉĉĉĉ ĉ drag Offset Ġ= Ġcurrent Offset Ċĉĉĉĉĉ ĉ else Ċĉĉĉĉĉĉ ĉ set Scroll Offset ( new Offset ) ĊĉĉĉĉĉĉĊĉĉĉĉĉ ĉ isSelected Ġ= Ġtrue Ċĉĉĉĉ ĉ }, Ċĉĉĉĉ ĉ on Drag Stopped Ġ= Ġ{ Ċĉĉĉĉĉ ĉ isSelected Ġ= Ġfalse Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ ) Ċĉĉĉ ĉ . absolute Offset ( x Ġ= Ġif Ġ( right Side ) Ġdisplacement . dp Ġelse Ġ- dis placement . dp ) Ċĉ ĉ ) Ġ{ ĊĉĉĉĊĉĉ ĉ Box ( Ċĉĉĉ ĉ Modifier Ċĉĉĉĉ ĉ . align ( Alignment . Top End ) Ċĉĉĉĉ ĉ . graphics Layer Ġ{ Ġtranslation Y Ġ= Ġconstraints . max Height . toFloat () Ġ* Ġnormalized Offset Position () Ġ} Ċĉĉĉĉ ĉ . padding ( horizontal Ġ= Ġpadding ) Ċĉĉĉĉ ĉ . width ( thickness ) Ċĉĉĉĉ ĉ . clip ( thumb Shape ) Ċĉĉĉĉ ĉ . background ( if Ġ( isSelected ) Ġthumb Selected Color Ġelse Ġthumb Color ) Ċĉĉĉĉ ĉ . fill Max Height ( normalized Thumb Size ()) Ċĉĉ ĉ ) Ċĉ ĉ } Ċ ĉ } Ċ } Ċ