/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 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 Ġcom . android . tools . adt ui . ui Ċ Ċ import Ġcom . android . annotations . concurrency . Ui Thread Ċ import Ġcom . android . tools . adt ui . model . Stop watch Ċ import Ġcom . android . tools . idea . concurrency . Future Callback Executor Ċ import Ġcom . android . tools . idea . concurrency . catch ing Ċ import Ġcom . android . tools . idea . concurrency . transform Ċ import Ġcom . intellij . openapi . Disposable Ċ import Ġcom . intellij . openapi . diagnostic . logger Ċ import Ġcom . intellij . ui . components . JB Panel Ċ import Ġcom . intellij . ui . scale . Scale Context Ċ import Ġcom . intellij . util . JB Hi DPI Scaled Image Ċ import Ġcom . intellij . util . concurrency . App Executor Util Ċ import Ġcom . intellij . util . concurrency . Ed t ExecutorService Ċ import Ġjava . awt . Graphics Ċ import Ġjava . awt . Image Ċ import Ġjava . awt . event . Component Adapter Ċ import Ġjava . awt . event . Component Event Ċ import Ġjava . util . concurrent . Future Ċ import Ġjava . util . concurrent . TimeUnit Ċ Ċ /** Ċ Ġ* ĠA Ġ[ JB Panel ] Ġthat Ġshows Ġan Ġ[ Image ] Ġas Ġbackground , Ġscaled Ġto Ġfit Ġpre serving Ġthe Ġaspect Ġratio . Ċ Ġ* ĠAllows Ġthe Ġ[ Image ] Ġto Ġbe Ġregenerated Ġthrough Ġa Ġ[ Scaled Image Provider ] Ġwhen Ġthe Ġpanel Ġsize Ċ Ġ* Ġchanges . ĠSupports ĠHi DPI Ġif Ġ[ image ] Ġis Ġa Ġ[ JB Hi DPI Scaled Image ]. Ċ Ġ*/ Ċ @ Ui Thread Ċ open Ġclass ĠScaling Image Panel Ġ: ĠJ B Panel < Image Panel >( true ), ĠDis posable Ġ{ ĊĠ Ġprivate Ġval ĠLOG Ġ= Ġlogger < Scaling Image Panel >() ĊĠ Ġprivate Ġval Ġstop watch Ġ= ĠStop watch () ĊĠ Ġprivate Ġval Ġed t Executor Ġ= ĠFuture Callback Executor ( Ed t ExecutorService . getInstance ()) ĊĠ Ġprivate Ġval Ġbounded Executor Ġ= ĠApp Executor Util . create Bounded Application Pool Executor (" Scaling Image Panel ", Ġ 1 ) ĊĠ Ġprivate Ġval Ġtask Executor Ġ= ĠFuture Callback Executor ( bounded Executor ) ĊĠ Ġprivate Ġval Ġresized Listener Ġ= Ġobject Ġ: ĠComponent Adapter () Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġcomponent Res ized ( e : ĠComponent Event ?) Ġ{ ĊĠĠĠĠĠ Ġsuper . component Res ized ( e ) ĊĠĠĠĠĠ Ġrep aint Async () ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĠ Ġprivate Ġvar Ġprevious Future : ĠFuture < Unit >? Ġ= Ġnull ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠThe Ġ[ Image ] Ġto Ġdraw ĊĠĠ Ġ*/ ĊĠ Ġvar Ġimage : ĠImage ? Ġ= Ġnull ĊĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠ Ġfield Ġ= Ġvalue ĊĠĠĠĠĠ Ġrep aint () ĊĠĠĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠWhere Ġthe Ġimage Ġshould Ġbe Ġ" gray ed Ġout " Ġ( as Ġinactive ) Ġor Ġnot ĊĠĠ Ġ*/ ĊĠ Ġvar Ġactive : ĠBoolean Ġ= Ġtrue ĊĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠ Ġfield Ġ= Ġvalue ĊĠĠĠĠĠ Ġrep aint () ĊĠĠĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠThe Ġ[ Scaled Image Provider ] Ġto Ġre compute Ġthe Ġ[ image ] Ġwhen Ġthe Ġcomponent Ġsize Ġchanges ĊĠĠ Ġ*/ ĊĠ Ġvar Ġscaled Image Provider : ĠSca led Image Provider ? Ġ= Ġnull ĊĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠ Ġfield Ġ= Ġvalue ĊĠĠĠĠĠ Ġif Ġ( value Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġremove Component Listener ( res ized Listener ) ĊĠĠĠĠĠĠĠ Ġrep aint () ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġadd Component Listener ( res ized Listener ) ĊĠĠĠĠĠĠĠ Ġimage Ġ= Ġvalue . initial Image ĊĠĠĠĠĠĠĠ Ġrep aint Async () ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġdispose () Ġ{ ĊĠĠĠ Ġremove Component Listener ( res ized Listener ) ĊĠĠĠ Ġprevious Future ?. cancel ( false ) ĊĠĠĠ Ġbounded Executor . shutdown Now () ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġpaint Component ( g : ĠGraphics ) Ġ{ ĊĠĠĠ Ġsuper . paint Component ( g ) ĊĠĠĠ Ġpaint Panel Image ( g , Ġimage , Ġactive , Ġfalse ) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġrep aint Async () Ġ{ ĊĠĠĠ Ġscaled Image Provider ?. let Ġ{ Ġprovider Ġ-> ĊĠĠĠĠĠ Ġval Ġwidth Ġ= Ġthis . width . toDouble () ĊĠĠĠĠĠ Ġval Ġheight Ġ= Ġthis . height . toDouble () ĊĠĠĠĠĠ Ġval Ġctx Ġ= ĠScale Context . create ( this ) ĊĠĠĠĠĠ Ġval Ġnew Future Ġ= Ġtask Executor . execute Async Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠEmpty Ġbody Ġso Ġthat Ġpotential Ġfuture Ġcancellation Ġaffect Ġthe Ġactual ĊĠĠĠĠĠĠĠ Ġ// Ġheavy Ġprocessing Ġcall Ġ( in Ġthe Ġtransform Ġbelow ) ĊĠĠĠĠĠ Ġ}. transform ( task Executor ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠNote : ĠThis Ġblock Ġwill Ġnever Ġexecute Ġif Ġthere Ġare Ġmultiple Ġrep aint Async ĊĠĠĠĠĠĠĠ Ġ// Ġrequest Ġ( see Ġfuture Ġcancellation Ġbelow ) ĊĠĠĠĠĠĠĠ Ġstop watch . start () ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġprovider . create Scaled Image ( ctx , Ġwidth , Ġheight ) ĊĠĠĠĠĠĠĠ Ġstop watch . stop () ĊĠĠĠĠĠĠĠ ĠLOG . debug (" create Scale Image ( scale Context =${ ctx }, Ġw =${ width }, Ġh =${ height }) Ġis Ġdone Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" in Ġ${ TimeUnit . NAN O SECONDS . to Millis ( stop watch . total Running Time Ns )} Ġm sec ") ĊĠĠĠĠĠĠĠ Ġresult ĊĠĠĠĠĠ Ġ}. transform ( ed t Executor ) Ġ{ Ġnew Image Ġ-> ĊĠĠĠĠĠĠĠ Ġ// ĠUpdate Ġimage Ġon ĠE DT Ġthread Ġ( this Ġwill Ġrep aint ) ĊĠĠĠĠĠĠĠ ĠLOG . debug (" Updating Ġpanel Ġimage Ġ( scale Context =${ ctx }, Ġuser Width =${ user Width ( new Image )}, Ġpixel Width =${ pixel Width ( new Image )}) ") ĊĠĠĠĠĠĠĠ Ġif Ġ( provider Ġ== Ġscaled Image Provider ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġimage Ġ= Ġnew Image ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ}. catch ing ( ed t Executor , ĠException :: class . java ) Ġ{ Ġe Ġ-> ĊĠĠĠĠĠĠĠ ĠLOG . warn (" Error Ġloading Ġscaled Ġimage ", Ġe ) ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġ// ĠCancel Ġprevious Ġblock Ġof Ġwork Ġso Ġthat Ġwe Ġdon 't Ġwaste ĠCPU Ġcycles Ġscaling ĊĠĠĠĠĠ Ġ// Ġan Ġimage Ġthat Ġwill Ġnever Ġbe Ġdisplayed Ġ( we Ġonly Ġcare Ġabout Ġthe Ġlast Ġone ) ĊĠĠĠĠĠ Ġprevious Future ?. cancel ( false ) ĊĠĠĠĠĠ Ġprevious Future Ġ= Ġnew Future ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġuser Width ( img : ĠImage ): ĠInt Ġ{ ĊĠĠĠ Ġif Ġ( img Ġis ĠJ B Hi DPI Scaled Image ) Ġ{ ĊĠĠĠĠĠ Ġreturn Ġimg . getUser Width ( null ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠ Ġreturn Ġimg . getWidth ( null ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġpixel Width ( img : ĠImage ): ĠInt Ġ{ ĊĠĠĠ Ġif Ġ( img Ġis ĠJ B Hi DPI Scaled Image ) Ġ{ ĊĠĠĠĠĠ Ġreturn Ġimg . get Real Width ( null ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠ Ġreturn Ġimg . getWidth ( null ) ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ