/* Ċ Ġ* Ġ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 . foundation Ċ Ċ import Ġandroidx . compose . animation . animated Color Ċ import Ġandroidx . compose . animation . core . Animated Value Ċ import Ġandroidx . compose . animation . core . Animation Constants . Infinite Ċ import Ġandroidx . compose . animation . core . keyframes Ċ import Ġandroidx . compose . animation . core . repeat able Ċ import Ġandroidx . compose . foundation . layout . default Min Size Constraints Ċ import Ġandroidx . compose . foundation . text . Core TextField Ċ import Ġandroidx . compose . foundation . text . TextField Delegate Ċ import Ġandroidx . compose . runtime . Composable Ċ import Ġandroidx . compose . runtime . Stable Ċ import Ġandroidx . compose . runtime . getValue Ċ import Ġandroidx . compose . runtime . mutable State Of Ċ import Ġandroidx . compose . runtime . on Commit Ċ import Ġandroidx . compose . runtime . remember Ċ import Ġandroidx . compose . runtime . setValue Ċ import Ġandroidx . compose . ui . Content Draw Scope Ċ import Ġandroidx . compose . ui . Draw Modifier Ċ import Ġandroidx . compose . ui . Modifier Ċ import Ġandroidx . compose . ui . composed Ċ import Ġandroidx . compose . ui . focus . Experimental Focus Ċ import Ġandroidx . compose . ui . focus . is Focused Ċ import Ġandroidx . compose . ui . focus Observer Ċ import Ġandroidx . compose . ui . geometry . Offset Ċ import Ġandroidx . compose . ui . geometry . Rect Ċ import Ġandroidx . compose . ui . graphics . Color Ċ import Ġandroidx . compose . ui . graphics . use OrElse Ċ import Ġandroidx . compose . ui . text . Annotated String Ċ import Ġandroidx . compose . ui . text . Internal Text Api Ċ import Ġandroidx . compose . ui . text . Software Keyboard Controller Ċ import Ġandroidx . compose . ui . text . Text Layout Result Ċ import Ġandroidx . compose . ui . text . TextStyle Ċ import Ġandroidx . compose . ui . text . input . I me Action Ċ import Ġandroidx . compose . ui . text . input . Keyboard Type Ċ import Ġandroidx . compose . ui . text . input . TextField Value Ċ import Ġandroidx . compose . ui . text . input . Visual Transformation Ċ import Ġandroidx . compose . ui . unit . dp Ċ import Ġandroidx . compose . ui . util . annotation . Visible ForTesting Ċ Ċ // ĠTODO ( b / 1 5 1 9 4 0 5 4 3 ): ĠRemove Ġthis Ġvariable Ġwhen Ġwe Ġhave Ġa Ġsolution Ġfor Ġid ling Ġanimations Ċ /** Ġ@ suppress Ġ*/ Ċ @ Internal Foundation Api Ċ var Ġblink ing Cursor Enabled : ĠBoolean Ġ= Ġtrue ĊĠĠĠ Ġ@ Visible ForTesting ĊĠĠĠ Ġset Ċ Ċ /** Ċ Ġ* ĠComp osable Ġthat Ġenables Ġusers Ġto Ġedit Ġtext Ġvia Ġhardware Ġor Ġsoftware Ġkeyboard . Ċ Ġ* Ċ Ġ* ĠWh enever Ġthe Ġuser Ġedits Ġthe Ġtext , Ġ[ on Value Change ] Ġis Ġcalled Ġwith Ġthe Ġmost Ġup Ġto Ġdate Ġstate Ċ Ġ* Ġrepresented Ġby Ġ[ TextField Value ]. Ġ[ TextField Value ] Ġcontains Ċ Ġ* Ġthe Ġtext Ġentered Ġby Ġuser , Ġas Ġwell Ġas Ġselection , Ġcursor Ġand Ġtext Ġcomposition Ġinformation . Ċ Ġ* ĠPlease Ġcheck Ġ[ TextField Value ] Ġfor Ġthe Ġdescription Ġof Ġits Ġcontents . Ċ Ġ* Ċ Ġ* ĠIt Ġis Ġcr uc ial Ġthat Ġthe Ġvalue Ġprovided Ġin Ġthe Ġ[ on Value Change ] Ġis Ġfed Ġback Ġinto Ġ[ Base TextField ] Ġin Ċ Ġ* Ġorder Ġto Ġhave Ġthe Ġfinal Ġstate Ġof Ġthe Ġtext Ġbeing Ġdisplayed . ĠExample Ġusage : Ċ Ġ* Ġ@ sample Ġandroidx . compose . foundation . samples . TextField Sample Ċ Ġ* Ċ Ġ* ĠPlease Ġkeep Ġin Ġmind Ġthat Ġ[ on Value Change ] Ġis Ġuseful Ġto Ġbe Ġin formed Ġabout Ġthe Ġlatest Ġstate Ġof Ġthe Ċ Ġ* Ġtext Ġinput Ġby Ġusers , Ġhowever Ġit Ġis Ġgenerally Ġnot Ġrecommended Ġto Ġmodify Ġthe Ġvalues Ġin Ġthe Ċ Ġ* Ġ[ TextField Value ] Ġthat Ġyou Ġget Ġvia Ġ[ on Value Change ] Ġcallback . ĠAny Ġchange Ġto Ġthe Ġvalues Ġin Ċ Ġ* Ġ[ TextField Value ] Ġmay Ġresult Ġin Ġa Ġcontext Ġreset Ġand Ġend Ġup Ġwith Ġinput Ġsession Ġrestart . ĠSuch Ċ Ġ* Ġa Ġscenario Ġwould Ġcause Ġg lit ches Ġin Ġthe ĠUI Ġor Ġtext Ġinput Ġexperience Ġfor Ġusers . Ċ Ġ* Ċ Ġ* ĠThis Ġcomp osable Ġprovides Ġbasic Ġtext Ġediting Ġfunctionality , Ġhowever Ġdoes Ġnot Ġinclude Ġany Ċ Ġ* Ġdecor ations Ġsuch Ġas Ġborders , Ġhints / placeholder . ĠA Ġdesign Ġsystem Ġbased Ġimplementation Ġsuch Ġas Ċ Ġ* ĠMaterial ĠDesign ĠF illed Ġtext Ġfield Ġis Ġtypically Ġwhat Ġis Ġneeded Ġto Ġcover Ġmost Ġof Ġthe Ġneeds . ĠThis Ċ Ġ* Ġcomp osable Ġis Ġdesigned Ġto Ġbe Ġused Ġwhen Ġa Ġcustom Ġimplementation Ġfor Ġdifferent Ġdesign Ġsystem Ġis Ċ Ġ* Ġneeded . Ċ Ġ* Ċ Ġ* ĠFor Ġexample , Ġif Ġyou Ġneed Ġto Ġinclude Ġa Ġhint Ġin Ġyour ĠTextField Ġyou Ġcan Ġwrite Ġa Ġcomp osable Ġas Ġbelow : Ċ Ġ* Ġ@ sample Ġandroidx . compose . foundation . samples . Placeholder TextField Sample Ċ Ġ* Ċ Ġ* Ġ@ param Ġvalue ĠThe Ġ[ TextField Value ] Ġto Ġbe Ġshown Ġin Ġthe Ġ[ Base TextField ]. Ċ Ġ* Ġ@ param Ġon Value Change ĠCalled Ġwhen Ġthe Ġinput Ġservice Ġupdates Ġvalues Ġin Ċ Ġ* Ġ[ TextField Value ]. Ċ Ġ* Ġ@ param Ġmodifier Ġoptional Ġ[ Modifier ] Ġfor Ġthis Ġtext Ġfield . Ċ Ġ* Ġ@ param ĠtextColor Ġ[ Color ] Ġto Ġapply Ġto Ġthe Ġtext . ĠIf Ġ[ Color . Unset ], Ġand Ġ[ text Style ] Ġhas Ġno Ġcolor Ċ Ġ* Ġset , Ġthis Ġwill Ġbe Ġ[ content Color ]. Ċ Ġ* Ġ@ param Ġtext Style ĠStyle Ġconfiguration Ġthat Ġapplies Ġat Ġcharacter Ġlevel Ġsuch Ġas Ġcolor , Ġfont Ġetc . Ċ Ġ* ĠThe Ġdefault Ġ[ text Style ] Ġuses Ġthe Ġ[ current TextStyle ] Ġdefined Ġby Ġthe Ġtheme Ċ Ġ* Ġ@ param Ġkeyboard Type ĠThe Ġkeyboard Ġtype Ġto Ġbe Ġused Ġin Ġthis Ġtext Ġfield . ĠNote Ġthat Ġthis Ġinput Ġtype Ċ Ġ* Ġis Ġhon ored Ġby ĠI ME Ġand Ġshows Ġcorresponding Ġkeyboard Ġbut Ġthis Ġis Ġnot Ġguaranteed . ĠFor Ġexample , Ċ Ġ* Ġsome ĠI ME Ġmay Ġsend Ġnon - ASCII Ġcharacter Ġeven Ġif Ġyou Ġset Ġ[ Keyboard Type . Ascii ]. Ċ Ġ* Ġ@ param Ġ ime Action ĠThe ĠI ME Ġaction . ĠThis ĠI ME Ġaction Ġis Ġhon ored Ġby ĠI ME Ġand Ġmay Ġshow Ġspecific Ġicons Ċ Ġ* Ġon Ġthe Ġkeyboard . ĠFor Ġexample , Ġsearch Ġicon Ġmay Ġbe Ġshown Ġif Ġ[ I me Action . Search ] Ġis Ġspecified . Ċ Ġ* ĠThen , Ġwhen Ġuser Ġtap Ġthat Ġkey , Ġthe Ġ[ on I me ActionPerformed ] Ġcallback Ġis Ġcalled Ġwith Ġspecified Ċ Ġ* ĠI me Action . Ċ Ġ* Ġ Ġ* Ġ@ param Ġon I me ActionPerformed ĠCalled Ġwhen Ġthe Ġinput Ġservice Ġrequested Ġan ĠI ME Ġaction . ĠWhen Ġthe Ċ Ġ* Ġinput Ġservice Ġemitted Ġan ĠI ME Ġaction , Ġthis Ġcallback Ġis Ġcalled Ġwith Ġthe Ġemitted ĠI ME Ġaction . ĠNote Ċ Ġ* Ġthat Ġthis ĠI ME Ġaction Ġmay Ġbe Ġdifferent Ġfrom Ġwhat Ġyou Ġspecified Ġin Ġ[ ime Action ]. Ċ Ġ* Ġ@ param Ġvisual Transformation ĠThe Ġvisual Ġtransformation Ġfilter Ġfor Ġchanging Ġthe Ġvisual Ċ Ġ* Ġrepresentation Ġof Ġthe Ġinput . ĠBy Ġdefault Ġno Ġvisual Ġtransformation Ġis Ġapplied . Ċ Ġ* Ġ@ param Ġon Text Layout ĠCallback Ġthat Ġis Ġexecuted Ġwhen Ġa Ġnew Ġtext Ġlayout Ġis Ġcalculated . Ċ Ġ* Ġ@ param Ġon TextInput Started ĠCallback Ġthat Ġis Ġexecuted Ġwhen Ġthe Ġinitialization Ġhas Ġdone Ġfor Ċ Ġ* Ġcommunic ating Ġwith Ġplatform Ġtext Ġinput Ġservice , Ġe . g . Ġsoftware Ġkeyboard Ġon ĠAndroid . ĠCalled Ġwith Ċ Ġ* Ġ[ Software Keyboard Controller ] Ġinstance Ġwhich Ġcan Ġbe Ġused Ġfor Ġrequesting Ġinput Ġshow / hide Ġsoftware Ċ Ġ* Ġkeyboard . Ċ Ġ* Ġ@ param Ġcursor Color ĠColor Ġof Ġthe Ġcursor . Ċ Ġ* Ċ Ġ* Ġ@ see ĠText FieldValue Ċ Ġ* Ġ@ see ĠI me Action Ċ Ġ* Ġ@ see ĠKeyboard Type Ċ Ġ* Ġ@ see ĠVisual Transformation Ċ Ġ*/ Ċ @ Composable Ċ @ Experimental Foundation Api Ċ @ Opt In ( Experimental Focus :: class ) Ċ fun ĠBase TextField ( ĊĠĠĠ Ġvalue : ĠText FieldValue , ĊĠĠĠ Ġon Value Change : Ġ( TextField Value ) Ġ-> ĠUnit , ĊĠĠĠ Ġmodifier : ĠModifier Ġ= ĠModifier , ĊĠĠĠ ĠtextColor : ĠColor Ġ= ĠColor . Unset , ĊĠĠĠ Ġtext Style : ĠTextStyle Ġ= Ġcurrent TextStyle (), ĊĠĠĠ Ġkeyboard Type : ĠKeyboard Type Ġ= ĠKeyboard Type . Text , ĊĠĠĠ Ġ ime Action : ĠI me Action Ġ= ĠI me Action . Unspecified , ĊĠĠĠ Ġon I me ActionPerformed : Ġ( I me Action ) Ġ-> ĠUnit Ġ= Ġ{}, ĊĠĠĠ Ġvisual Transformation : ĠVisual Transformation Ġ= ĠVisual Transformation . None , ĊĠĠĠ Ġon Text Layout : Ġ( Text Layout Result ) Ġ-> ĠUnit Ġ= Ġ{}, ĊĠĠĠ Ġon TextInput Started : Ġ( Software Keyboard Controller ) Ġ-> ĠUnit Ġ= Ġ{}, ĊĠĠĠ Ġcursor Color : ĠColor Ġ= Ġcontent Color () Ċ ) Ġ{ ĊĠĠĠ Ġval Ġcolor Ġ= ĠtextColor . use OrElse Ġ{ Ġtext Style . color . use OrElse Ġ{ Ġcontent Color () Ġ} Ġ} ĊĠĠĠ Ġval Ġmerged Style Ġ= Ġtext Style . merge ( TextStyle ( color Ġ= Ġcolor )) ĊĊĠĠĠ Ġ// Ġcursor Ġwith Ġblink ing Ġanimation ĊĠĠĠ Ġval Ġcursor State : ĠCursor State Ġ= Ġremember Ġ{ ĠCursor State () Ġ} ĊĠĠĠ Ġval Ġcursor Needed Ġ= Ġcursor State . focused Ġ&& Ġvalue . selection . collapsed ĊĠĠĠ Ġval Ġanim Color Ġ= Ġanimated Color ( cursor Color ) ĊĠĠĠ Ġon Commit ( cursor Color , Ġcursor State . focused , Ġvalue ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( cursor Needed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO ( b / 1 5 1 9 4 0 5 4 3 ): ĠDisable Ġblink ing Ġin Ġtests Ġuntil Ġwe Ġhandle Ġid ling Ġanimations ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Opt In ( Internal Foundation Api :: class ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( blink ing Cursor Enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġanim Color . animate To ( Color . Transparent , Ġanim Ġ= Ġrepeat able ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġiterations Ġ= ĠIn finite , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġanimation Ġ= Ġkey frames Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġduration Millis Ġ= Ġ 1 0 0 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcursor Color Ġat Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcursor Color Ġat Ġ 4 9 9 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠColor . Transparent Ġat Ġ 5 0 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ)) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġanim Color . snap To ( cursor Color ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġanim Color . snap To ( Color . Transparent ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġon Dispose Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġanim Color . stop () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġcursor Modifier Ġ= Ġif Ġ( cursor Needed ) Ġ{ ĊĠĠĠĠĠĠĠ ĠModifier . cursor Modifier ( anim Color , Ġcursor State , Ġvalue , Ġvisual Transformation ) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ ĠModifier ĊĠĠĠ Ġ} ĊĠĠĠ ĠCore TextField ( ĊĠĠĠĠĠĠĠ Ġvalue Ġ= Ġvalue , ĊĠĠĠĠĠĠĠ Ġmodifier Ġ= Ġmodifier ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. focus Observer Ġ{ Ġcursor State . focused Ġ= Ġit . is Focused Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. default Min Size Constraints ( min Width Ġ= ĠDefault TextField Width ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. then ( cursor Modifier ), ĊĠĠĠĠĠĠĠ Ġon Value Change Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Value Change ( it ) ĊĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠ Ġtext Style Ġ= Ġmerged Style , ĊĠĠĠĠĠĠĠ Ġkeyboard Type Ġ= Ġkeyboard Type , ĊĠĠĠĠĠĠĠ Ġ ime Action Ġ= Ġ ime Action , ĊĠĠĠĠĠĠĠ Ġon I me ActionPerformed Ġ= Ġon I me ActionPerformed , ĊĠĠĠĠĠĠĠ Ġvisual Transformation Ġ= Ġvisual Transformation , ĊĠĠĠĠĠĠĠ Ġon Text Layout Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcursor State . layout Result Ġ= Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Text Layout ( it ) ĊĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠ Ġon TextInput Started Ġ= Ġon TextInput Started ĊĠĠĠ Ġ) Ċ } Ċ Ċ @ Stable Ċ private Ġclass ĠCursor State Ġ{ ĊĠĠĠ Ġvar Ġfocused Ġby Ġmutable State Of ( false ) ĊĠĠĠ Ġvar Ġlayout Result Ġby Ġmutable State Of < Text Layout Result ? >( null ) Ċ } Ċ Ċ private Ġfun ĠModifier . cursor Modifier ( ĊĠĠĠ Ġcolor : ĠAnimated Value < Color , Ġ* >, ĊĠĠĠ Ġcursor State : ĠCursor State , ĊĠĠĠ Ġtext FieldValue : ĠText FieldValue , ĊĠĠĠ Ġvisual Transformation : ĠVisual Transformation Ċ ) Ġ= Ġcomposed Ġ{ ĊĠĠĠ Ġremember ( cursor State , Ġtext FieldValue , Ġvisual Transformation ) Ġ{ ĊĠĠĠĠĠĠĠ ĠCursor Modifier ( color , Ġcursor State , Ġtext FieldValue , Ġvisual Transformation ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġdata Ġclass ĠCursor Modifier ( ĊĠĠĠ Ġval Ġcolor : ĠAnimated Value < Color , Ġ* >, ĊĠĠĠ Ġval Ġcursor State : ĠCursor State , ĊĠĠĠ Ġval Ġtext FieldValue : ĠText FieldValue , ĊĠĠĠ Ġval Ġvisual Transformation : ĠVisual Transformation Ċ ) Ġ: ĠDraw Modifier Ġ{ ĊĠĠĠ Ġoverride Ġfun ĠContent Draw Scope . draw () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( color . value . alpha Ġ!= Ġ 0 f ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransformed Ġ= Ġvisual Transformation . filter ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAnnot ated String ( text FieldValue . text ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Opt In ( Internal Text Api :: class ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransformed Text Ġ= Ġtext FieldValue . composition ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTextField Delegate . apply Composition Decoration ( it , Ġtransformed ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ?: Ġtransformed ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcursor Width Ġ= ĠCursor Thickness . value Ġ* Ġdensity ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcursor Height Ġ= Ġcursor State . layout Result ?. size ?. height ?. toFloat () Ġ?: Ġ 0 f ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcursor Rect Ġ= Ġcursor State . layout Result ?. get Cursor Rect ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransformed Text . offset Map . original To Trans formed ( text FieldValue . selection . start ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ?: ĠRect ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 f , Ġ 0 f , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcursor Width , Ġcursor Height ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcursor X Ġ= Ġ( cursor Rect . left Ġ+ Ġcursor Width Ġ/ Ġ 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. coerce At Most ( size . width Ġ- Ġcursor Width Ġ/ Ġ 2 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġdraw Line ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcolor . value , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOffset ( cursor X , Ġcursor Rect . top ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOffset ( cursor X , Ġcursor Rect . bottom ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠstrokeWidth Ġ= Ġcursor Width ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġdraw Content () ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġval ĠCursor Thickness Ġ= Ġ 2 . dp Ċ private Ġval ĠDefault TextField Width Ġ= Ġ 2 8 0 . dp