123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960(*********************************************************************************)(* OCaml-Stk *)(* *)(* Copyright (C) 2023-2024 INRIA All rights reserved. *)(* Author: Maxence Guesdon, INRIA Saclay *)(* *)(* This program is free software; you can redistribute it and/or modify *)(* it under the terms of the GNU General Public License as *)(* published by the Free Software Foundation, version 3 of the License. *)(* *)(* This program is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU General Public License for more details. *)(* *)(* You should have received a copy of the GNU General Public *)(* License along with this program; if not, write to the Free Software *)(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA *)(* 02111-1307 USA *)(* *)(* As a special exception, you have permission to link this program *)(* with the OCaml compiler and distribute executables, as long as you *)(* follow the requirements of the GNU GPL in regard to all of the *)(* software in the executable aside from the OCaml compiler. *)(* *)(* Contact: Maxence.Guesdon@inria.fr *)(* *)(*********************************************************************************)[@@@landmark"auto"]exceptionProperty_existsofstringtype'apost_action=|Resize|Render|Actionof('a->unit)moduleId=Misc.Id()type'aprop=Id.ttype'atransition=start:'a->stop:'a->float->'aletdummy_trans~start~stop_=stoptypeprop_value=..moduletypeProp=sigvalid:Id.ttypetvalname:stringvalcompare:t->t->intvalwrapper:tOcf.Wrapper.toptionvalfrom_prop_value:prop_value->tvalto_prop_value:t->prop_valuevalafter:tpost_actionlistvaldefault:toptionvalinherited:boolvaltransition:ttransitionoptionendletprops=ref([||]:(moduleProp)array)letprops_by_name=refSmap.emptyletget_propid=try!props.(Id.to_intid)with_->Log.err(funm->m"Invalid prop id %a"Id.ppid);assertfalseletnameid=letmoduleP=(valget_propid:Prop)inP.nameletprop_wrapper:'aprop->'aOcf.Wrapper.toption=funid->letmoduleP=(valget_propid:Prop)inObj.magicP.wrapperletinheritedid=letmoduleP=(valget_propid:Prop)inP.inheritedletdefault_value:'aprop->'aoption=funid->letmoduleP=(valget_propid:Prop)inObj.magicP.defaultlettransition:'aprop->'atransitionoption=funid->letmoduleP=(valget_propid:Prop)inObj.magicP.transitionletafter:'aprop->'apost_actionlist=funid->letmoduleP=(valget_propid:Prop)inObj.magicP.afterletto_prop_value:'aprop->'a->prop_value=funidv->letmoduleP=(valget_propid)inP.to_prop_value(Obj.magicv)letfrom_prop_value:'aprop->prop_value->'a=funidv->letmoduleP=(valget_propid)inObj.magic(P.from_prop_valuev)moduleMap=Id.Maptypet={mutablet:prop_valueMap.t}letempty()={t=Map.empty}letset:t->'aprop->'a->unit=funtidv->t.t<-Map.addid(to_prop_valueidv)t.tletset_opttp=function|None->t.t<-Map.removept.t|Somev->settpvletvar_of_stringstr=letlen=String.lengthstriniflen>0&&String.getstr0='$'thenSome(String.substr1(len-1))elseNoneletmap_set_from_json=refSmap.emptyletset_prop_from_json?varstnamejson=matchSmap.find_optname!map_set_from_jsonwith|None->()|Somef->f?varstjsonletset_from_json?varst=function|`Assocl->List.iter(fun(name,json)->set_prop_from_json?varstnamejson)l|_->Log.err(funm->m"Props.set_from_json: not an `Assoc")letto_json?with_doct=letfid(v:prop_value)acc=letmoduleP=(valget_propid:Prop)inmatchP.wrapperwith|None->acc|Somew->(P.name,w.to_json?with_doc(P.from_prop_valuev))::accin`Assoc(Map.foldft.t[])letrecexpand_jsonvarsjson=matchjsonwith|`Strings->(matchvar_of_stringswith|None->json|Somev->matchSmap.find_optvvarswith|None->Log.warn(funm->m"Unknown variable %s"s);json|Somejson->expand_jsonvarsjson)|`Assocl->`Assoc(List.map(fun(str,json)->(str,expand_jsonvarsjson))l)|`Listl->`List(List.map(expand_jsonvars)l)|`Tuplel->`Tuple(List.map(expand_jsonvars)l)|`Variant(x,Somejson)->`Variant(x,Some(expand_jsonvarsjson))|_->jsonletwrapper=letfrom_json?defjson=lett=empty()inset_from_jsontjson;tinOcf.Wrapper.maketo_jsonfrom_jsonletcompare_prop_value=ref(funv1v2->assertfalse)letregister_compare_prop_valuef=letc=!compare_prop_valueincompare_prop_value:=fcmoduletypePT=sigtypetvalcompare:t->t->intvalwrapper:tOcf.Wrapper.toptionvaltransition:ttransitionoptionendtype'amk_prop=?after:'apost_actionlist->?default:'a->?inherited:bool->?transition:'atransition->string->'apropmoduletypeProp_type=sigincludePTvalfrom_prop_value:prop_value->tvalto_prop_value:t->prop_valuevalmk_prop:tmk_propendletregister_propp=letmoduleP=(valp:Prop)in(matchId.to_intP.idwith|0->(* first prop *)props:=Array.make1p|nwhenn>0->letprops2=Array.make(n+1)pinArray.blit!props0props20(Array.length!props);props:=props2|_->assertfalse);props_by_name:=Smap.addP.nameP.id!props_by_nameletprop_to_string:'aprop->'a->string=funpv->letmoduleP=(valget_propp:Prop)inmatchP.wrapperwith|None->"<no printer>"|Somew->Yojson.Safe.to_string(w.to_json(Obj.magicv))moduleAdd_prop_type(T:PT)=structtypet=T.ttypeprop_value+=VofT.tletcompfallbackv1v2=matchv1,v2with|Vv1,Vv2->T.comparev1v2|V_,_->-1|_,V_->1|_->fallbackv1v2let()=register_compare_prop_valuecompletcompare=T.compareletwrapper=T.wrapperlettransition=T.transitionletfrom_prop_value=function|Vv->v|x->assertfalseletto_prop_valuev=Vvletmk_prop:?after:T.tpost_actionlist->?default:T.t->?inherited:bool->?transition:T.ttransition->string->T.tprop=fun?(after=[])?default?(inherited=true)?transitionname->matchSmap.find_optname!props_by_namewith|Some_->raise(Property_existsname)|None->letid=Id.gen()inletmoduleM=structtypet=T.tletid=idletname=nameletcompare=T.compareletwrapper=T.wrapperletfrom_prop_value=from_prop_valueletto_prop_value=to_prop_valueletafter=afterletdefault=defaultletinherited=inheritedlettransition=matchtransitionwithNone->T.transition|x->xendinletset_from_json?varstjson=matchM.wrapperwith|None->()|Somew->matchjsonwith|`Null->set_opttidNone|json->letjson=matchvarswith|None->json|Somevars->expand_jsonvarsjsoninletv=w.Ocf.Wrapper.from_json?def:defaultjsoninsettidvinmap_set_from_json:=Smap.addnameset_from_json!map_set_from_json;register_prop(moduleM);idendletint_transition~start~stopr=truncate(floatstart+.(min1.r)*.(float(stop-start)))moduleTInt=structtypet=intletcompare=Int.compareletwrapper=SomeOcf.Wrapper.intlettransition=Someint_transitionendmodulePInt=Add_prop_type(TInt)letfloat_transition~start~stopr=start+.(min1.r)*.(stop-.start)modulePFloat=Add_prop_type(structtypet=floatletcompare=Float.compareletwrapper=SomeOcf.Wrapper.floatlettransition=Somefloat_transitionend)modulePBool=Add_prop_type(structtypet=boolletcompare=Bool.compareletwrapper=SomeOcf.Wrapper.boollettransition=Some(fun~start~stopr->ifr>=1.thenstopelsestart)end)modulePString=Add_prop_type(structtypet=stringletcompare=String.compareletwrapper=SomeOcf.Wrapper.stringlettransition=Noneend)moduleTUchar=structtypet=Uchar.tletcompare=Uchar.compareletwrapper=letto_json?with_docc=`Int(Uchar.to_intc)inletfrom_json?def=function|`Intn->Uchar.of_intn|json->Ocf.invalid_valuejsoninSome(Ocf.Wrapper.maketo_jsonfrom_json)lettransition=NoneendmodulePUchar=Add_prop_type(TUchar)moduleTColor=structtypet=Color.tletcompare=Color.compareletwrapper=SomeColor.ocf_wrapperlettransition=letf~start~stopq=let(r,g,b,a)=Color.to_int8sstartinlet(r2,g2,b2,a2)=Color.to_int8sstopinletr=int_transition~start:r~stop:r2qinletg=int_transition~start:g~stop:g2qinletb=int_transition~start:b~stop:b2qinleta=int_transition~start:a~stop:a2qinColor.of_rgbargbainSomefendmodulePColor=Add_prop_type(TColor)modulePFont_desc=Add_prop_type(structtypet=Font.font_descletcompare=Font.font_desc_compareletwrapper=SomeFont.font_desc_wrapperlettransition=Noneend)letcomparep1p2=Map.compare!compare_prop_valuep1.tp2.tmoduleTProps=structtypenonrect=tletcompare=compareletwrapper=Somewrapperlettransition=NoneendmodulePProps=Add_prop_type(TProps)moduleTKeystate=structtypet=Key.keystateletcompare=Key.compare_keystateletwrapper=SomeKey.keystate_ocf_wrapperlettransition=NoneendmodulePKeystate=Add_prop_type(TKeystate)type'atrbl={top:'a;right:'a;bottom:'a;left:'a}lettrbl~top~right~bottom~left={top;right;bottom;left}lettrbl_toprightbottomleft={top;right;bottom;left}lettrbl__x=trbl_xxxxlettrbl_of?top?right?bottom?leftt=lettop=Option.fold~none:t.top~some:(funx->x)topinletright=Option.fold~none:t.right~some:(funx->x)rightinletbottom=Option.fold~none:t.bottom~some:(funx->x)bottominletleft=Option.fold~none:t.left~some:(funx->x)leftintrbl~top~right~bottom~leftlettrbl_comparecomparet1t2=matchcomparet1.topt2.topwith|0->(matchcomparet1.rightt2.rightwith|0->(matchcomparet1.bottomt2.bottomwith|0->comparet1.leftt2.left|n->n)|n->n)|n->nlettrbl_ocf_wrapperw=letto_j?with_doct=`Assoc["top",w.Ocf.Wrapper.to_json?with_doct.top;"right",w.to_json?with_doct.right;"bottom",w.to_json?with_doct.bottom;"left",w.to_json?with_doct.left;]inletfrom_j?def=function|`List[t;r;b;l]->trbl_(w.Ocf.Wrapper.from_jsont)(w.from_jsonr)(w.from_jsonb)(w.from_jsonr)|`List[tb;rl]->lettb=w.from_jsontbinletrl=w.from_jsonrlintrbl_tbrltbrl|`Assocl->beginletgetfd=Option.map(w.from_json?def:None)(List.assoc_optfdl)inmatchget"top",get"right",get"bottom",get"left"with|Sometop,Someright,Somebottom,Someleft->trbl~top~right~bottom~left|top,right,bottom,left->matchdefwith|Somed->trbl_of?top?right?bottom?leftd|None->Ocf.json_error(Printf.sprintf"Missing field (top|right|bottom|left) in %s"(Yojson.Safe.to_string(`Assocl)))end|json->trbl__(w.from_jsonjson)inOcf.Wrapper.maketo_jfrom_jlettrbl_transitionf~start~stopr={top=f~start:start.top~stop:stop.topr;right=f~start:start.right~stop:stop.rightr;bottom=f~start:start.bottom~stop:stop.bottomr;left=f~start:start.left~stop:stop.leftr;}modulePTrbl(T:PT)=Add_prop_type(structtypet=T.ttrblletcompare=trbl_compareT.compareletwrapper=matchT.wrapperwith|None->None|Somew->Some(trbl_ocf_wrapperw)lettransition=Option.maptrbl_transitionT.transitionend)modulePTrbl_int=PTrbl(TInt)modulePTrbl_color=PTrbl(TColor)letlist_transitionf~start~stopr=List.map2(funstartstop->f~start~stopr)startstopmodulePList(T:PT)=Add_prop_type(structtypet=T.tlistletcompare=List.compareT.compareletwrapper=matchT.wrapperwith|None->None|Somew->Some(Ocf.Wrapper.listw)lettransition=Option.maplist_transitionT.transitionend)modulePPair(T1:PT)(T2:PT)=Add_prop_type(structtypet=T1.t*T2.tletcompare(a1,b1)(a2,b2)=matchT1.comparea1a2with|0->T2.compareb1b2|n->nletwrapper=matchT1.wrapperwith|None->None|Somew1->matchT2.wrapperwith|None->None|Somew2->Some(Ocf.Wrapper.pairw1w2)lettransition=matchT1.transition,T2.transitionwith|None,None->None|Somef,None->Some(fun~start:(a1,_)~stop:(a2,b2)r->f~start:a1~stop:a2r,b2)|None,Somef->Some(fun~start:(_,b1)~stop:(a2,b2)r->a2,f~start:b1~stop:b2r)|Somef1,Somef2->Some(fun~start:(a1,b1)~stop:(a2,b2)r->(f1~start:a1~stop:a2r,f2~start:b1~stop:b2r))end)modulePTriple(T1:PT)(T2:PT)(T3:PT)=Add_prop_type(structtypet=T1.t*T2.t*T3.tletcompare(a1,b1,c1)(a2,b2,c2)=matchT1.comparea1a2with|0->(matchT2.compareb1b2with|0->T3.comparec1c2|n->n)|n->nletwrapper=matchT1.wrapperwith|None->None|Somew1->matchT2.wrapperwith|None->None|Somew2->matchT3.wrapperwith|None->None|Somew3->Some(Ocf.Wrapper.triplew1w2w3)lettransition=matchT1.transition,T2.transition,T3.transitionwith|None,None,None->None|Somef,None,None->Some(fun~start:(a1,_,_)~stop:(a2,b2,c2)r->f~start:a1~stop:a2r,b2,c2)|None,Somef,None->Some(fun~start:(_,b1,_)~stop:(a2,b2,c2)r->a2,f~start:b1~stop:b2r,c2)|None,None,Somef->Some(fun~start:(_,_,c1)~stop:(a2,b2,c2)r->a2,b2,f~start:c1~stop:c2r)|Somef1,Somef2,None->Some(fun~start:(a1,b1,_)~stop:(a2,b2,c2)r->(f1~start:a1~stop:a2r,f2~start:b1~stop:b2r,c2))|Somef1,None,Somef3->Some(fun~start:(a1,_,c1)~stop:(a2,b2,c2)r->(f1~start:a1~stop:a2r,b2,f3~start:c1~stop:c2r))|None,Somef2,Somef3->Some(fun~start:(_,b1,c1)~stop:(a2,b2,c2)r->(a2,f2~start:b1~stop:b2r,f3~start:c1~stop:c2r))|Somef1,Somef2,Somef3->Some(fun~start:(a1,b1,c1)~stop:(a2,b2,c2)r->(f1~start:a1~stop:a2r,f2~start:b1~stop:b2r,f3~start:c1~stop:c2r))end)modulePPair_float=PPair(PFloat)(PFloat)letint_prop=PInt.mk_propletfloat_prop=PFloat.mk_propletcolor_prop=PColor.mk_propletbool_prop=PBool.mk_propletstring_prop=PString.mk_propletuchar_prop=PUchar.mk_propletfont_desc_prop=PFont_desc.mk_propletint_trbl_prop=PTrbl_int.mk_propletcolor_trbl_prop=PTrbl_color.mk_propletfloat_pair_prop=PPair_float.mk_propletprops_prop=PProps.mk_propletkeystate_prop=PKeystate.mk_proptypetext_valign=|Baseline|Sub|Super|Top|Text_top|Middle|Bottom|Text_bottomletstring_of_text_valign=function|Baseline->"baseline"|Sub->"sub"|Super->"super"|Top->"top"|Text_top->"text_top"|Middle->"middle"|Bottom->"bottom"|Text_bottom->"text_bottom"lettext_valign_of_strings=matchString.lowercase_asciiswith|"baseline"->Baseline|"sub"->Sub|"super"->Super|"top"->Top|"text-top"->Text_top|"middle"->Middle|"bottom"->Bottom|"text-bottom"->Text_bottom|_->Log.warn(funm->m"invalid text_valign value %S; defaulting to baseline"s);Baselinelettext_valign_wrapper=letto_json?with_docm=`String(string_of_text_valignm)inletfrom_json?def=function|`Strings->text_valign_of_strings|json->Ocf.invalid_valuejsoninOcf.Wrapper.maketo_jsonfrom_jsonmoduleTText_valign=structtypet=text_valignletcompare=Stdlib.compareletwrapper=Sometext_valign_wrapperlettransition=NoneendmodulePText_valign=Add_prop_type(TText_valign)lettext_valign=PText_valign.mk_prop~default:Baseline~inherited:false"text_valign"typeselection_mode=|Sel_none|Sel_single|Sel_browse|Sel_multipleletstring_of_selection_mode=function|Sel_none->"none"|Sel_single->"single"|Sel_browse->"browse"|Sel_multiple->"multiple"letselection_mode_of_strings=matchString.lowercase_asciiswith|"none"->Sel_none|"single"->Sel_single|"browse"->Sel_browse|"multiple"->Sel_multiple|_->Log.warn(funm->m"invalid selection_mode %S; defaulting to Sel_multiple"s);Sel_multipleletselection_mode_wrapper=letto_json?with_docm=`String(string_of_selection_modem)inletfrom_json?def=function|`Strings->selection_mode_of_strings|json->Ocf.invalid_valuejsoninOcf.Wrapper.maketo_jsonfrom_jsonmoduleTSel_mode=structtypet=selection_modeletcompare=Stdlib.compareletwrapper=Someselection_mode_wrapperlettransition=NoneendmodulePSel_mode=Add_prop_type(TSel_mode)letselection_mode=PSel_mode.mk_prop~default:Sel_multiple~inherited:false"selection_mode"typeorientation=Vertical|Horizontalletstring_of_orientation=function|Vertical->"vertical"|Horizontal->"horizontal"letorientation_of_strings=matchString.lowercase_asciiswith|"vertical"->Vertical|"horizontal"->Horizontal|_->Log.warn(funm->m"invalid orientation %S; defaulting to Vertical"s);Verticalletorientation_wrapper=letto_json?with_docm=`String(string_of_orientationm)inletfrom_json?def=function|`Strings->orientation_of_strings|json->Ocf.invalid_valuejsoninOcf.Wrapper.maketo_jsonfrom_jsonmoduleTOrientation=structtypet=orientationletcompare=Stdlib.compareletwrapper=Someorientation_wrapperlettransition=NoneendmodulePOrientation=Add_prop_type(TOrientation)letorientation=POrientation.mk_prop~after:[Resize]~default:Vertical~inherited:false"orientation"letpp_prop:'aprop->Format.formatter->'a->unit=funp->letmoduleP=(valget_propp:Prop)infunppfv->letto_string=prop_to_stringpinFormat.pp_print_stringppf(to_stringv)letto_stringt=letl=Map.fold(funid(v:prop_value)->funacc->letp=get_propidinletmoduleP=(valp:Prop)inletstr=Printf.sprintf"%s: %s"P.name(prop_to_stringid(P.from_prop_valuev))instr::acc)t.t[]inString.concat", "lletppppft=Format.pp_open_boxppf0;Map.iter(funid(v:prop_value)->letp=get_propidinletmoduleP=(valp:Prop)inFormat.fprintfppf"%s: %s,@,"P.name(prop_to_stringid(P.from_prop_valuev)))t.t;Format.pp_close_boxppf()letdupt={t=t.t}letmerge=letfuse_inheritedkv1v2=matchv1,v2with|None,None->None|None,Some_->v2|Some_,Nonewhenuse_inherited->letmoduleP=(valget_propk:Prop)inifP.inheritedthenv1elseNone|Some_,None->v1|Some_,Some_->v2infun?(use_inherited=false)t1t2->{t=Map.merge(fuse_inherited)t1.tt2.t}letopt:t->'aprop->'aoption=funtid->matchMap.find_optidt.twith|None->None|Some(v:prop_value)->Some(from_prop_valueidv)letget:t->'aprop->'a=funtid->matchopttidwith|Somev->v|None->letmoduleP=(valget_propid:Prop)inmatchP.defaultwith|Somev->Obj.magic(*allow P.t to escape*)v|None->Misc.missing_propP.name(to_stringt)typeprops=tletpadding=int_trbl_prop~inherited:false~after:[Resize]~default:(trbl__0)"padding"letmargin=int_trbl_prop~inherited:false~after:[Resize]~default:(trbl__0)"margin"letborder_width=int_trbl_prop~inherited:false~after:[Resize]~default:(trbl__0)"border_width"letborder_color=color_trbl_prop~inherited:false~after:[Render]~default:(trbl__Color.transparent)"border_color"letborder_color_hover=color_trbl_prop~inherited:false~after:[Render]~default:(trbl__Color.transparent)"border_color_hover"letborder_color_selected=color_trbl_prop~inherited:false~after:[Render]~default:(trbl__Color.transparent)"border_color_selected"letborder_color_focused=color_trbl_prop~inherited:false~after:[Render]~default:(trbl__Color.transparent)"border_color_focused"letactive=bool_prop~after:[Render]~default:false~inherited:false"active"(*
let margin_left = int_prop "margin_left"
let margin_right = int_prop "margin_right"
let margin_top = int_prop "margin_top"
let margin_bottom = int_prop "margin_bottom"
*)lethexpand=int_prop~after:[Resize]~inherited:false~default:1"hexpand"letvexpand=int_prop~after:[Resize]~inherited:false~default:1"vexpand"letvisible=bool_prop~inherited:false~after:[Resize]~default:true"visible"letsensitive=bool_prop~inherited:false~after:[Render]~default:true"sensitive"letinsensitive_color_mask=color_prop~after:[Render]~default:0x80808044l"insensitive_color_mask"lethfill=bool_prop~after:[Resize]~inherited:false~default:true"hfill"letvfill=bool_prop~after:[Resize]~inherited:false~default:true"vfill"lethalign=float_prop~after:[Render]~default:0.5"halign"letvalign=float_prop~after:[Render]~default:0.5"valign"letwidth=int_prop~after:[Resize]"width"letheight=int_prop~after:[Resize]"height"letmax_width=int_prop~after:[Resize]"max_width"letmax_height=int_prop~after:[Resize]"max_height"letfill=bool_prop~after:[Render]~inherited:false~default:false"fill"letbg_fill_borders=bool_prop~after:[Render]~inherited:false~default:false"bg_fill_borders"letfont_desc=font_desc_prop~after:[Resize]~default:(Font.font_desc~size:14"DejaVu Sans")"font_desc"letbold=bool_prop~after:[Resize]"bold"letitalic=bool_prop~after:[Resize]"italic"letfg_color=color_prop~after:[Render]~default:0x333333ffl"fg_color"letfg_color_hover=color_prop~after:[Render]~default:0xdd2222ffl"fg_color_hover"letfg_color_selected=color_prop~after:[Render]~default:0x444444ffl"fg_color_selected"letfg_color_focused=color_prop~after:[Render]"fg_color_focused"letbg_color=color_prop~after:[Render]~inherited:false~default:Color.transparent"bg_color"letbg_color_hover=color_prop~after:[Render]~inherited:false~default:0xaabbbbffl"bg_color_hover"letbg_color_selected=color_prop~after:[Render]~inherited:false~default:0x2222ddffl"bg_color_selected"letbg_color_focused=color_prop~after:[Render]~inherited:false"bg_color_focused"letselection_fg_color=color_prop~after:[Render]~default:0x444444ffl"selection_fg_color"letselection_bg_color=color_prop~after:[Render]~default:0x2222ddffl"selection_bg_color"letinput_bg_color=color_prop~after:[Render]~default:0xeeeeeeffl"input_bg_color"letinput_ghost_color=color_prop~after:[Render]~default:0xccccccffl"input_ghost_color"letopacity=float_prop~after:[Render]"opacity"letcurrent_line_bg_color=color_prop~after:[Render]"current_line_bg_color"letclick_mask=color_prop~after:[Render]~default:0xffffff88l"click_mask"(* Widget has the global input focus, i.e. its window
has the global input focus and the widget has
its is_focus property set to true. *)lethas_focus=bool_prop~inherited:false~after:[Action(funb->ifbthenTsdl.Sdl.start_text_input()elseTsdl.Sdl.stop_text_input());Render]~default:false"has_focus"letis_focus=bool_prop~after:[Render]~default:false~inherited:false"is_focus"letfocusable=bool_prop~inherited:false~default:false"focusable"letcan_focus=bool_prop~inherited:false~default:true"can_focus"letshow_on_focus=bool_prop~inherited:false~default:true"show_on_focus"letselected=bool_prop~after:[Render]~default:false~inherited:false"selected"lettext=string_prop~after:[Resize]"text"letglyph=int_prop~after:[Resize]"glyph"letghost_text=string_prop~after:[Render]"ghost_text"leteditable=bool_prop~inherited:false~default:true"editable"letcursor_width=int_prop~default:2~after:[Render]"cursor_width"letcursor_color=color_prop~default:Color.red~after:[Render]"cursor_color"letactive_cursor_color=color_prop~default:Color.red~after:[Render]"active_cursor_color"letscrollbar_width=int_prop~default:12"scrollbar_width"letscrollbar_handle_min_size=int_prop~default:40"scrollbar_handle_min_size"letscrollbar_handle_color=color_prop~default:0x2222dd00l"scrollbar_handle_color"letscrollbar_bg_color=color_prop~default:0xaaaaff99l"scrollbar_bg_color"letget_fontprops=letdesc=getpropsfont_descinletdesc=matchoptpropsboldwith|None->desc|Somebold->{descwithFont.bold}inletdesc=matchoptpropsitalicwith|None->desc|Someitalic->{descwithitalic}inFont.getdescletget_font_for_charpropsc=letfn=get_fontpropsinletcode=Uchar.to_intcinifFont.glyph_is_providedfncodethenfnelsematchFont.fallback_fontcodewith|None->[%debug"get_font_for_char %x: no fallback font"code];fn|Somefamily->[%debug"get_font_for_char %x"code];letdesc=getpropsfont_descintryFont.get{descwithfamily}withe->[%debug"Props.get_font_for_char %x: %s"code(Printexc.to_stringe)];fnletset_font_sizepsize=letd=getpfont_descinsetpfont_desc{dwithFont.size}letset_font_italicpitalic=letd=getpfont_descinsetpfont_desc{dwithFont.italic}letset_font_boldpbold=letd=getpfont_descinsetpfont_desc{dwithFont.bold}letset_font_familypfamily=letd=getpfont_descinsetpfont_desc{dwithFont.family}letset_font_underlinepunderline=letd=getpfont_descinsetpfont_desc{dwithFont.underline}letset_font_strikethroughpstrikethrough=letd=getpfont_descinsetpfont_desc{dwithFont.strikethrough}letset_font_kerningpkerning=letd=getpfont_descinsetpfont_desc{dwithFont.kerning}letset_font_outlinepoutline=letd=getpfont_descinsetpfont_desc{dwithFont.outline}letupdate:t->'aprop->'a->'aoptionoption=funtpv->matchMap.find_optpt.twith|None->settpv;SomeNone|Some(v0:prop_value)->letmoduleP=(valget_propp)inletv0=P.from_prop_valuev0inifP.comparev0(Obj.magicv)=0thenNoneelse(settpv;Some(Some(Obj.magicv0:'a)))letcleart=t.t<-Map.emptyletdefault=letp=empty()inpopenMiscletcreate()=lett=dupdefaultintletfold_registered_properties:(?default:'a->'aprop->'acc->'acc)->'acc->'acc=fun(f:?default:'a->'aprop->'acc->'acc)acc->Array.fold_right(fun(moduleP:Prop)acc->letdefault=default_valueP.idinf?defaultP.idacc)!propsaccletiter:('aprop->'a->unit)->t->unit=fun(f:'aprop->'a->unit)p->letgpv=fp(from_prop_valuepv)inMap.itergp.tletfold:('aprop->'a->'acc->'acc)->t->'acc->'acc=fun(f:'aprop->'a->'acc->'acc)pacc->letgpvacc=fp(from_prop_valuepv)accinMap.foldgp.taccletto_json:t->Yojson.Safe.t=funt->`Assoc(fold(funpvacc->letmoduleP=(valget_propp:Prop)inmatchP.wrapperwith|None->acc|Somew->(P.name,w.to_json(Obj.magicv))::acc)t[])