package Ġcom . so yle . stories . common Ċ Ċ import Ġcom . so yle . stories . di . DI Ċ import Ġcom . so yle . stories . project . Project Scope Ċ import Ġcom . so yle . stories . so yle stories . Application Scope Ċ import Ġjavafx . beans . binding . Boolean Expression Ċ import Ġjavafx . beans . binding . Integer Binding Ċ import Ġjavafx . beans . property .* Ċ import Ġjavafx . beans . value . ChangeListener Ċ import Ġjavafx . beans . value . Observable Value Ċ import Ġjavafx . collections . List ChangeListener Ċ import Ġjavafx . collections . Observable List Ċ import Ġjavafx . geometry . Bounds Ċ import Ġjavafx . scene . Node Ċ import Ġjavafx . scene . control .* Ċ import Ġjavafx . scene . control . skin . TextArea Skin Ċ import Ġjavafx . scene . control . skin . Virtual Flow Ċ import Ġjavafx . scene . image . ImageView Ċ import Ġjavafx . scene . input . ContextMenu Event Ċ import Ġjavafx . scene . text . Text Ċ import Ġkotlinx . coroutines . Coroutine Scope Ċ import Ġkotlinx . coroutines . Job Ċ import Ġt orn ad of x .* Ċ import Ġt orn ad of x . Style sheet . Companion . selected Ċ import Ġjava . util .* Ċ import Ġkotlin . collections . Linked HashSet Ċ import Ġkotlin . contracts . Experimental Contracts Ċ import Ġkotlin . contracts . Invocation Kind Ċ import Ġkotlin . contracts . contract Ċ import Ġkotlin . reflect . K Property Ċ import Ġkotlin . reflect . K Property 1 Ċ import Ġkotlin . reflect . full . member Functions Ċ import Ġkotlin . reflect . full . member Properties Ċ Ċ /** Ċ Ġ* ĠCreated Ġby ĠB rend an Ċ Ġ* ĠDate : Ġ 2 / 1 4 / 2 0 2 0 Ċ Ġ* ĠTime : Ġ 9 : 4 9 ĠPM Ċ Ġ*/ ĊĊ Ċ /** Ċ Ġ* ĠListen Ġfor Ġchanges Ġto Ġthis Ġobservable . ĠOptionally Ġonly Ġlisten Ġuntil Ġthe Ġpredicate Ġreturns Ġtrue . Ċ Ġ* ĠThe Ġlambda Ġreceives Ġthe Ġchanged Ġvalue Ġwhen Ġthe Ġchange Ġoccurs , Ġwhich Ġmay Ġbe Ġnull , Ċ Ġ*/ Ċ fun Ġ< T > ĠObservable Value < T >. onChange Until ( until : Ġ( T ?) Ġ-> ĠBoolean , Ġop : Ġ( T ?) Ġ-> ĠUnit ) Ġ{ Ċ ĉ val Ġlistener Ġ= Ġobject Ġ: ĠChange Listener < T > Ġ{ Ċĉ ĉ override Ġfun Ġchanged ( observable : ĠObservable Value < out ĠT > ?, ĠoldValue : ĠT , ĠnewValue : ĠT ) Ġ{ Ċĉĉ ĉ if Ġ( until ( newValue )) Ġ{ Ċĉĉĉ ĉ remove Listener ( this ) Ċĉĉ ĉ } Ċĉĉ ĉ op ( newValue ) Ċĉ ĉ } Ċ ĉ } Ċ ĉ addListener ( listener ) Ċ } Ċ Ċ /** Ċ Ġ* ĠListen Ġfor Ġchanges Ġto Ġthis Ġobservable . ĠOptionally Ġonly Ġlisten Ġuntil Ġthe Ġpredicate Ġreturns Ġtrue . Ċ Ġ* ĠThe Ġlambda Ġreceives Ġthe Ġchanged Ġvalue Ġwhen Ġthe Ġchange Ġoccurs , Ġwhich Ġmay Ġbe Ġnull , Ċ Ġ*/ Ċ fun Ġ< T > ĠObservable List < T >. onChange Until ( until : Ġ( List < T > ?) Ġ-> ĠBoolean , Ġop : Ġ( List < T > ?) Ġ-> ĠUnit ) Ġ{ Ċ ĉ val Ġlistener Ġ= Ġobject Ġ: ĠList ChangeListener < T > Ġ{ Ċĉ ĉ override Ġfun ĠonChanged ( c : ĠList ChangeListener . Change < out ĠT > ?) Ġ{ Ċĉĉ ĉ if Ġ( until ( c ?. list )) Ġ{ Ċĉĉĉ ĉ remove Listener ( this ) Ċĉĉ ĉ } Ċĉĉ ĉ op ( c ?. list ) Ċĉ ĉ } Ċ ĉ } Ċ ĉ addListener ( listener ) Ċ } Ċ Ċ fun Ġ< T > ĠObservable Value < T >. onChange Until ( until : ĠBoolean Expression , Ġop : Ġ( T ?) Ġ-> ĠUnit ) Ġ{ Ċ ĉ val Ġlistener Ġ= ĠChange Listener < T > Ġ{ Ġobservable , ĠoldValue , ĠnewValue Ġ-> Ġop ( newValue ) Ġ} Ċ ĉ until . onChange Until ({ Ġit Ġ!= Ġtrue Ġ}) Ġ{ Ċĉ ĉ if Ġ( it Ġ!= Ġtrue ) Ġremove Listener ( listener ) Ċ ĉ } Ċ ĉ addListener ( listener ) Ċ } Ċ Ċ fun Ġ< T Ġ: ĠAny > ĠObservable Value < T >. onChange With Current ( op : Ġ( T ?) Ġ-> ĠUnit ) Ġ{ Ċ ĉ onChange ( op ) Ċ ĉ op ( value ) Ċ } Ċ Ċ fun Ġ< T , ĠR , ĠL Ġ: ĠList < R >> ĠItem ViewModel < T >. bind ImmutableList ( property : ĠK Property 1 < T , ĠL >): ĠSimple List Property < R > Ġ= ĊĠ Ġbind Ġ{ Ġitem ?. let ( property )?. to Observable (). to Property () Ġ} Ġas ĠSimple List Property < R > Ċ Ċ fun Ġ< T , ĠR , ĠL Ġ: ĠSet < R >> ĠItem ViewModel < T >. bind Immutable Set ( property : ĠK Property 1 < T , ĠL >): ĠSimple SetProperty < R > Ġ= ĊĠ Ġbind Ġ{ Ġitem ?. let ( property )?. to Observable (). to Property () Ġ} Ġas ĠSimple SetProperty < R > Ċ Ċ fun Ġ< T , ĠR , ĠS , ĠL Ġ: ĠMap < R , ĠS >> ĠItem ViewModel < T >. bind Immutable Map ( property : ĠK Property 1 < T , ĠL >): ĠSimple Map Property < R , ĠS > Ġ= ĊĠ Ġbind Ġ{ Ġitem ?. let ( property )?. to Observable (). to Property () Ġ} Ġas ĠSimple Map Property < R , ĠS > Ċ Ċ fun Ġ< S > ĠTable Column < S , Ġ* >. set Static Column Index ( index : ĠInt ) Ġ{ Ċ ĉ var Ġprevent Loop Ġ= Ġfalse Ċ ĉ table View Property (). onChange Ġ{ Ġtable View Ġ-> Ċĉ ĉ table View ?. columns ?. onChange Ġ{ Ċĉĉ ĉ if Ġ( prevent Loop ) Ġreturn @ onChange Ċĉĉ ĉ val ĠcurrentIndex Ġ= Ġcolumns . indexOf ( this ) Ċĉĉ ĉ val Ġdesired Index : ĠInt Ġ= Ġcalculate Index ( index ) Ċĉĉ ĉ if Ġ( currentIndex Ġ!= Ġdesired Index ) Ġ{ Ċĉĉĉ ĉ run Later Ġ{ Ċĉĉĉĉ ĉ prevent Loop Ġ= Ġtrue Ċĉĉĉĉ ĉ table View . columns . move ( this @ set Static Column Index , Ġdesired Index ) Ċĉĉĉĉ ĉ prevent Loop Ġ= Ġfalse Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ċĉ ĉ } Ċ ĉ } Ċ ĉ val ĠcurrentIndex Ġ= Ġcolumns . indexOf ( this ) Ċ ĉ val Ġdesired Index : ĠInt Ġ= Ġcalculate Index ( index ) Ċ ĉ if Ġ( currentIndex Ġ!= Ġdesired Index ) Ġ{ Ċĉ ĉ prevent Loop Ġ= Ġtrue Ċĉ ĉ table View . columns . move ( this @ set Static Column Index , Ġdesired Index ) Ċĉ ĉ prevent Loop Ġ= Ġfalse Ċ ĉ } Ċ } Ċ Ċ private Ġfun Ġ< S > ĠTable Column < S , Ġ* >. calculate Index ( index : ĠInt ): ĠInt Ġ{ Ċ ĉ val Ġcolumns Ġ= Ġtable View ?. columns ?. toList () Ġ?: Ġreturn Ġ- 1 Ċ ĉ return Ġif Ġ( index Ġ>= Ġ 0 ) Ġ{ Ċĉ ĉ if Ġ( columns . size Ġ<= Ġindex ) Ġ{ Ċĉĉ ĉ // Ġplace Ġcolumn Ġat Ġend Ġof Ġcolumn Ġlist Ċĉĉ ĉ columns . size Ġ- Ġ 1 Ċĉ ĉ } Ġelse Ġ{ Ċĉĉ ĉ index Ċĉ ĉ } Ċ ĉ } Ġelse Ġ{ Ċĉ ĉ // Ġnegative Ġindices Ġare Ġcalculated Ġfrom Ġthe Ġend Ġof Ġthe Ġcolumn Ġlist Ċĉ ĉ ( columns . size Ġ+ Ġindex ). coerce At Least ( 0 ) Ċ ĉ } Ċ } Ċ Ċ fun Ġ< T > Ġasync ( scope : ĠApplication Scope , Ġblock : Ġsuspend ĠCor outine Scope . () Ġ-> ĠT ): ĠJob Ġ{ Ċ ĉ return ĠDI . resolve < Thread Transformer >( scope ). async Ġ{ Ġblock () Ġ} Ċ } Ċ inline Ġfun Ġ< T > Ġasync ( scope : ĠProject Scope , Ġno inline Ġblock : Ġsuspend ĠCor outine Scope . () Ġ-> ĠT ) Ġ= Ġasync ( scope . application Scope , Ġblock ) Ċ Ċ private Ġval ĠText Area Hidden ScrollBar s Key Ġ= Ġ" com . so yle . stories . hidden ScrollBar s " Ċ Ċ val ĠText Area . are ScrollBar s Hidden : ĠBoolean Ċ ĉ get () Ġ= Ġproperties . getValue ( TextArea Hidden ScrollBar s Key ) Ġas ? ĠBoolean Ġ?: Ġfalse Ċ Ċ fun ĠText Area . hide Scroll bars () Ġ{ Ċ ĉ properties [ TextArea Hidden ScrollBar s Key ] Ġ= Ġtrue Ċ ĉ val Ġskin Listener Ġ= Ġskin Listener @{ Ġit : ĠSk in < *> ? Ġ-> Ċĉ ĉ if Ġ( it Ġ! is ĠText Area Skin ) Ġreturn @ skin Listener Ċĉ ĉ it . children . filter Is Instance < ScrollPane >(). first OrNull ()?. apply Ġ{ Ċĉĉ ĉ v bar Policy Ġ= ĠScroll Pane . ScrollBar Policy . NE VER Ċĉ ĉ } Ċ ĉ } Ċ ĉ skin Property (). onChange ( skin Listener ) Ċ ĉ skin Listener ( skin ) Ċ } Ċ Ċ /** Ċ Ġ* ĠCalculates Ġthe Ġcurrent Ġamount Ġof Ġrows Ġin Ġthe Ġtextarea Ġregardless Ċ Ġ* Ġof Ġ" word Wrap " Ġset Ġto Ġ` true ` Ġor Ġ` false `. Ċ Ġ* Ċ Ġ* Ġ@ return Ġthe Ġcurrent Ġcount Ġof Ġrows ; Ġ` 0 ` Ġif Ġthe Ġcount Ġcould Ġnot Ġbe Ġdetermined Ċ Ġ*/ Ċ private Ġfun ĠText Area . calculate RowCount (): ĠInt Ġ{ Ċ ĉ var Ġcurrent RowCount Ġ= Ġ 0 Ċ ĉ val Ġhelper Ġ= ĠText () Ċ ĉ /* Ċĉ Ġ* ĠL ittle Ġperformance Ġimprovement : ĠIf Ġ" wrap Text " Ġis Ġset Ġto Ġfalse , Ġthen Ġthe Ċĉ Ġ* Ġlist Ġof Ġparagraphs Ġdirectly Ġcorresponds Ġto Ġthe Ġline Ġcount , Ġotherwise Ġwe Ġneed Ċĉ Ġ* Ġto Ġget Ġcre ative ... Ċĉ Ġ*/ if Ġ( this . is Wrap Text ) Ġ{ Ċĉ ĉ // Ġtext Ġneeds Ġto Ġbe Ġon Ġthe Ġscene Ċĉ ĉ val Ġtext : ĠText Ġ= Ġlookup (". text ") Ġas ? ĠText Ġ?: Ġreturn Ġcurrent RowCount Ċĉ ĉ /* ĊĉĠĠ Ġ* ĠNow Ġwe Ġjust Ġcount Ġthe Ġparagraphs : ĠIf Ġthe Ġparagraph Ġsize Ġis Ġless ĊĉĠĠ Ġ* Ġthan Ġthe Ġcurrent Ġwrapping Width Ġthen Ġincrement ; ĠOtherwise Ġuse Ġour ĊĉĠĠ Ġ* ĠText Ġhelper Ġinstance Ġto Ġcalculate Ġthe Ġchange Ġin Ġheight Ġfor Ġthe ĊĉĠĠ Ġ* Ġcurrent Ġparagraph Ġwith Ġ" wrapping Width " Ġset Ġto Ġthe Ġactual ĊĉĠĠ Ġ* Ġwrapping Width Ġof Ġthe ĠText Area Ġtext ĊĉĠĠ Ġ*/ helper . font Ġ= Ġfont Ċĉ ĉ for Ġ( paragraph Ġin Ġparagraphs ) Ġ{ Ċĉĉ ĉ helper . text Ġ= Ġparagraph . toString () Ċĉĉ ĉ val Ġlocal Bounds : ĠBounds Ġ= Ġhelper . bounds In Local Ċĉĉ ĉ val Ġparagraph Width : ĠDouble Ġ= Ġlocal Bounds . width Ċĉĉ ĉ current RowCount Ġ+= Ġif Ġ( paragraph Width Ġ> Ġtext . wrapping Width ) Ġ{ Ċĉĉĉ ĉ val Ġold Height : ĠDouble Ġ= Ġlocal Bounds . height Ċĉĉĉ ĉ // Ġthis Ġactually Ġsets Ġthe Ġautomatic Ġsize Ġadjustment Ġinto Ġmotion ... Ċĉĉĉ ĉ helper . wrapping Width Ġ= Ġtext . wrapping Width Ċĉĉĉ ĉ val Ġnew Height : ĠDouble Ġ= Ġhelper . bounds In Local . height Ċĉĉĉ ĉ // Ġ... and Ġwe Ġreset Ġit Ġafter Ġcomputation Ċĉĉĉ ĉ helper . wrapping Width Ġ= Ġ 0 . 0 Ċĉĉĉ ĉ ( new Height Ġ/ Ġold Height ). toInt () Ċĉĉ ĉ } Ġelse Ġ{ Ċĉĉĉĉ 1 Ċĉĉ ĉ } Ċĉ ĉ } Ċ ĉ } Ġelse Ġ{ Ċĉ ĉ current RowCount Ġ= Ġparagraphs . size Ċ ĉ } Ċ ĉ return Ġcurrent RowCount Ċ } Ċ Ċ val ĠText Area . rowCount Property Ċ ĉ get () Ġ= Ġproperties . get Or Put (" com . so yle . stories . rowCount Property ") Ġ{ Ċĉ ĉ wrap Text Property (). integer Binding ( text Property (), Ġwidth Property ()) Ġ{ Ċĉĉ ĉ calculate RowCount () Ċĉ ĉ } Ċ ĉ } Ġas ĠInteger Binding Ċ Ċ val ĠText Area . rowCount Ċ ĉ get () Ġ= Ġrow Count Property . get () Ċ Ċ fun Ġ< T Ġ: ĠNode > ĠT . exists When ( expr : ĠObservable Value < Boolean >): ĠT Ġ{ Ċ ĉ visible When ( expr ) Ċ ĉ managed Property (). clean Bind ( visible Property ()) Ċ ĉ return Ġthis Ċ } Ċ fun Ġ< T Ġ: ĠNode > ĠT . exists When ( expr : Ġ() Ġ-> ĠObservable Value < Boolean >): ĠT Ġ= Ġexists When ( expr ()) Ċ var Ġ< T Ġ: ĠNode > ĠT . exists : ĠBoolean Ċ ĉ get () Ġ= Ġvisible Property (). get () Ġ&& Ġmanaged Property (). get () Ċ ĉ set ( value ) Ġ{ Ċĉ ĉ visible Property (). set ( value ) Ċĉ ĉ managed Property (). set ( value ) Ċ ĉ } Ċ Ċ fun ĠNode . on Lo se Focus ( op : Ġ() Ġ-> ĠUnit ) Ġ= Ġfocused Property (). onChange Ġ{ Ġif Ġ(! Ġit ) Ġop () Ġ} Ċ Ċ val Ġ< T > ĠListView < T >. cells : ĠLinked HashSet < List Cell < T >> Ċ ĉ get () Ġ= Ġproperties . get Or Put (" com . so yle . stories . list view . cells ") Ġ{ ĠLinked HashSet < List Cell < T >>() Ġ} Ġas ĠLinked HashSet < List Cell < T >> Ċ Ċ fun Ġ< T > ĠListView < T >. size To Fit Items ( maximum Visible Items : ĠDouble Ġ= Ġ 1 1 . 5 ) Ċ { Ċ ĉ val ĠROW _ HEIGHT Ġ= Ġ( children Un modifiable . first OrNull () Ġas ? ĠVirtual Flow < List Cell < T >>) ?. first Visible Cell ?. height Ġ?: Ġ 2 4 . 0 Ċ ĉ val Ġcurrent Pref Height Ġ= Ġpref Height Ċ ĉ pref Height Ġ= Ġ( items . size Ġ* ĠROW _ HEIGHT ) Ġ+ Ġ 2 . 0 Ċ ĉ val Ġcurrent Max Height Ġ= ĠmaxHeight Ċ ĉ max Height Ġ= Ġ 2 . 0 Ġ+ Ġmaximum Visible Items Ġ* ĠROW _ HEIGHT Ċ ĉ if Ġ( pref Height Ġ!= Ġcurrent Pref Height Ġ|| ĠmaxHeight Ġ!= Ġcurrent Max Height ) Ġ{ Ċĉ ĉ request Layout () Ċ ĉ } Ċ } Ċ Ċ /** Ċ Ġ* ĠEnables Ġfile - level Ġvalues Ġto Ġhave Ġcss class Ġdelegate Ċ Ġ*/ Ċ operator Ġfun ĠCss Class Delegate . getValue ( nothing : ĠNothing ?, Ġproperty : ĠK Property < *> ): ĠCss Rule Ġ= ĠgetValue ( file Obj , Ġproperty ) Ċ private Ġval Ġfile Obj Ġ= ĠAny () Ċ Ċ fun ĠNode . apply ContextMenu ( context Menu : ĠContext Menu , Ġon Requested : Ġ( ContextMenu Event ?) Ġ-> ĠUnit Ġ= Ġ{}) Ċ { Ċ ĉ if Ġ( this Ġis ĠControl ) Ġ{ Ċĉ ĉ this . context Menu Ġ= Ġcontext Menu Ċ ĉ } Ġelse Ġ{ Ċĉ ĉ setOn ContextMenu Requested Ġ{ Ċĉĉ ĉ context Menu . show ( this , Ġit . screen X , Ġit . screen Y ) Ċĉĉ ĉ on Requested ( it ) Ċĉĉ ĉ it . consume () Ċĉ ĉ } Ċ ĉ } Ċ } Ċ Ċ /** Ċ Ġ* Ġif Ġthe Ġimage Ġis Ġfinished Ġloading , Ġthe Ġlistener Ġis Ġcalled Ġimmediately . Ġ ĠOtherwise , Ġwhen Ġthe Ġimage Ġfinishes Ġloading Ġor Ċ Ġ* Ġfails Ġto Ġload , Ġthe Ġlistener Ġwill Ġbe Ġcalled . Ġ ĠIf Ġthe Ġimage Ġfails Ġto Ġload , Ġ[ error ] Ġwill Ġbe Ġtrue . Ċ Ġ*/ Ċ @ Opt In ( Experimental Contracts :: class ) Ċ fun ĠImageView . on Image Loading Done ( listener : Ġ( error : ĠBoolean ) Ġ-> ĠUnit ) Ġ{ Ċ ĉ contract Ġ{ Ċĉ ĉ calls In Place ( listener , ĠInvocation Kind . EX ACT LY _ ON CE ) Ċ ĉ } Ċ ĉ var Ġwas Called Ġ= Ġfalse Ċ ĉ val Ġexactly One Call Listener Ġ= Ġ{ Ġerror : ĠBoolean Ġ-> Ċĉ ĉ if Ġ(! Ġwas Called ) Ġ{ Ċĉĉ ĉ was Called Ġ= Ġtrue Ċĉĉ ĉ listener ( error ) Ċĉ ĉ } Ċ ĉ } Ċ ĉ on Image Loading Done Exactly Once ( exact ly One Call Listener ) Ċ } Ċ Ċ private Ġfun ĠImageView . on Image Loading Done Exactly Once ( listener : Ġ( error : ĠBoolean ) Ġ-> ĠUnit ) Ġ{ Ċ ĉ if Ġ( image . isError ) Ġlistener ( true ) Ċ ĉ else Ġif Ġ( image . progress Ġ== Ġ 1 . 0 ) Ġlistener ( false ) Ċ ĉ else Ġ{ Ċĉ ĉ image . progress Property (). onChange Once Ġ{ Ċĉĉ ĉ on Image Loading Done ( listener ) Ċĉ ĉ } Ċĉ ĉ image . error Property (). onChange Once Ġ{ Ċĉĉ ĉ on Image Loading Done ( listener ) Ċĉ ĉ } Ċ ĉ } Ċ } Ċ Ċ fun ĠNode . make Selectable ( focus Tra versable : ĠBoolean Ġ= Ġthis . is Focus Tra versable , Ġselection Class : ĠCss Rule ? Ġ= Ġnull ): ĠBoolean Property Ġ{ Ċ ĉ val Ġselected Property Ġ= Ġtry Ġ{ Ċĉ ĉ this :: class . member Functions . find Ġ{ Ġit . name Ġ== Ġ" selected Property " Ġ} ?. call () Ġas ? ĠBoolean Property Ġ?: ĠSimple Boolean Property ( false ) Ċ ĉ } Ġcatch Ġ( t : ĠThrowable ) Ġ{ Ċĉ ĉ Simple Boolean Property ( false ) Ċ ĉ } ĊĊ ĉ properties [" selected Property "] Ġ= Ġselected Property ĊĊ ĉ is Focus Tra versable Ġ= Ġfocus Tra versable Ċ ĉ if Ġ( focus Tra versable ) Ġ{ Ċĉ ĉ focused Property (). onChange Ġ{ Ċĉĉ ĉ if Ġ( it ) Ġ{ ĊĊĉĉ ĉ } Ċĉ ĉ } Ċ ĉ } Ċ ĉ on Left Click Ġ{ Ġselected Property . set ( true ) Ġ} Ċ ĉ if Ġ( selection Class Ġ!= Ġnull ) Ġtoggle Class ( selection Class , Ġselected Property ) Ċ ĉ toggleClass ( selected , Ġselected Property ) ĊĊ ĉ return Ġselected Property Ċ } Ċ