tk.go 294 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376
  1. // Copyright 2024 The tk9.0-go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package tk9_0 // import "modernc.org/tk9.0"
  5. import (
  6. "bytes"
  7. "crypto/sha256"
  8. _ "embed"
  9. "encoding/base64"
  10. "errors"
  11. "fmt"
  12. "image"
  13. "image/png"
  14. "io/fs"
  15. "os"
  16. "path/filepath"
  17. "reflect"
  18. "runtime"
  19. "strconv"
  20. "strings"
  21. "sync/atomic"
  22. "time"
  23. "unsafe"
  24. "golang.org/x/net/html"
  25. libtk9_0 "modernc.org/libtk9.0"
  26. )
  27. const (
  28. // ThemeEnvVar, if non-blank and containing a valid built-in theme
  29. // name, is used to set the default application theme. Calling
  30. // StyleThemeUse() will override the default.
  31. ThemeEnvVar = "TK9_THEME"
  32. // ScaleEnvVar, if a valid (floating point) number, sets the TkScaling
  33. // value at package initialization to NativeScaling*TK9_SCALE.
  34. ScaleEnvVar = "TK9_SCALE"
  35. gnuplotTimeout = time.Minute //TODO do not let the UI freeze
  36. goarch = runtime.GOARCH
  37. goos = runtime.GOOS
  38. libVersion = libtk9_0.Version
  39. tcl_eval_direct = 0x40000
  40. tcl_ok = 0
  41. tcl_error = 1
  42. tcl_return = 2
  43. tcl_break = 3
  44. tcl_continue = 4
  45. disconnectButtonTooltip = "Disconnect the application"
  46. exitButtonTooltip = "Quit the application"
  47. )
  48. // NativeScaling is the value returned by TKScaling in package initialization before it is possibly
  49. // changed using the [ScaleEnvVar] value.
  50. var NativeScaling float64
  51. // App is the main/root application window.
  52. var App = &Window{}
  53. var target = fmt.Sprintf("%s/%s", goos, goarch)
  54. //TODO? ErrorMsg
  55. // Error modes
  56. const (
  57. // Errors will panic with a stack trace.
  58. PanicOnError = iota
  59. // Errors will be recorded into the Error variable using errors.Join
  60. CollectErrors
  61. )
  62. const (
  63. testHookWaitVar = "TK9_TEST_HOOK_WAIT"
  64. )
  65. type dllInfo struct {
  66. dll string
  67. initProc string
  68. }
  69. // ErrorMode selects the action taken on errors.
  70. var ErrorMode int
  71. // Error records errors when [CollectErrors] is true.
  72. var Error error
  73. var (
  74. _ Opt = (*MenuItem)(nil)
  75. _ Widget = (*Window)(nil)
  76. //go:embed embed/gotk.png
  77. icon []byte
  78. //go:embed embed/tklib/tooltip/tooltip.tcl
  79. tooltip []byte
  80. appDeiconified bool
  81. appIconPhotoDone bool // Whether user code performed App.IconPhoto
  82. appIconified bool
  83. appWithdrawn bool
  84. autocenterDisabled bool
  85. cleanupDirs []string
  86. exitHandler Opt
  87. finished atomic.Int32
  88. forcedX = -1
  89. forcedY = -1
  90. handlers = map[int32]*eventHandler{}
  91. id atomic.Int32
  92. initialized bool
  93. isBuilder = os.Getenv("MODERNC_BUILDER") != ""
  94. isVNC = os.Getenv("TK9_VNC") == "1"
  95. testHookWait = os.Getenv(testHookWaitVar)
  96. wmTitle string
  97. // https://pdos.csail.mit.edu/archive/rover/RoverDoc/escape_shell_table.html
  98. //
  99. // The following characters are dissallowed or have special meanings in Tcl and
  100. // so are escaped:
  101. //
  102. // &;`'"|*?~<>^()[]{}$\
  103. badChars = [...]bool{
  104. ' ': true,
  105. '"': true,
  106. '$': true,
  107. '&': true,
  108. '(': true,
  109. ')': true,
  110. '*': true,
  111. ';': true,
  112. '<': true,
  113. '>': true,
  114. '?': true,
  115. '[': true,
  116. '\'': true,
  117. '\\': true,
  118. '\n': true,
  119. '\r': true,
  120. '\t': true,
  121. ']': true,
  122. '^': true,
  123. '`': true,
  124. '{': true,
  125. '|': true,
  126. '}': true,
  127. '~': true,
  128. }
  129. //TODO remove the associated tcl var on window destroy event both from the
  130. // interp and this map.
  131. textVariables = map[*Window]string{} // : tclName
  132. variables = map[*Window]*VariableOpt{}
  133. windowIndex = map[string]*Window{}
  134. )
  135. func commonLazyInit() {
  136. // Convert DOS line endings to Unix before evaluating.
  137. // https://gitlab.com/cznic/tk9.0/-/issues/67
  138. eval(string(bytes.ReplaceAll(tooltip, []byte{'\r', '\n'}, []byte{'\n'})))
  139. }
  140. func checkSig(dir string, sig map[string]string) (r bool) {
  141. if dmesgs {
  142. dmesg("checkSig(%q, %q)", dir, sig)
  143. }
  144. if err := filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
  145. if err != nil {
  146. return err
  147. }
  148. if d.IsDir() {
  149. return nil
  150. }
  151. base := filepath.Base(path)
  152. sum := sig[base]
  153. if sum == "" {
  154. return nil
  155. }
  156. b, err := os.ReadFile(path)
  157. if err != nil {
  158. return err
  159. }
  160. if g, e := fmt.Sprintf("%0x", sha256.Sum256(b)), sum; g != e {
  161. return fmt.Errorf("check failed: %s %s != %s", path, g, e)
  162. }
  163. delete(sig, base)
  164. return nil
  165. }); err != nil || len(sig) != 0 {
  166. if dmesgs {
  167. dmesg("checkSig(%q) failed: %v", dir, err)
  168. }
  169. return false
  170. }
  171. return true
  172. }
  173. // Returns a single Tcl string, no braces, except "{}" is returned for s == "".
  174. func tclSafeString(s string) string {
  175. if s == "" {
  176. return "{}"
  177. }
  178. const badString = "&;`'\"|*?~<>^()[]{}$\\\n\r\t "
  179. if strings.ContainsAny(s, badString) {
  180. var b strings.Builder
  181. for _, c := range s {
  182. switch {
  183. case int(c) < len(badChars) && badChars[c]:
  184. fmt.Fprintf(&b, "\\x%02x", c)
  185. default:
  186. b.WriteRune(c)
  187. }
  188. }
  189. s = b.String()
  190. }
  191. return s
  192. }
  193. // Same as tclSafeStrings but does not escape <>.
  194. func tclSafeStringBind(s string) string {
  195. if s == "" {
  196. return "{}"
  197. }
  198. const badString = "&;`'\"|*?~^()[]{}$\\\n\r\t "
  199. if strings.ContainsAny(s, badString) {
  200. var b strings.Builder
  201. for _, c := range s {
  202. switch {
  203. case int(c) < len(badChars) && badChars[c]:
  204. fmt.Fprintf(&b, "\\x%02x", c)
  205. default:
  206. b.WriteRune(c)
  207. }
  208. }
  209. s = b.String()
  210. }
  211. return s
  212. }
  213. // Returns a space separated list of safe Tcl strings.
  214. func tclSafeList(list ...any) string {
  215. var a []string
  216. for _, v := range list {
  217. a = append(a, tclSafeString(fmt.Sprint(v)))
  218. }
  219. return strings.Join(a, " ")
  220. }
  221. // Returns a space separated list of safe Tcl strings.
  222. func tclSafeStrings(s ...string) string {
  223. var a []string
  224. for _, v := range s {
  225. a = append(a, tclSafeString(v))
  226. }
  227. return strings.Join(a, " ")
  228. }
  229. // Returns a Tcl string that is safe inside {...}
  230. func tclSafeInBraces(s string) string {
  231. const badString = "}\\\n\r\t "
  232. if strings.ContainsAny(s, badString) {
  233. var b strings.Builder
  234. for _, c := range s {
  235. switch {
  236. case int(c) < len(badMLChars) && badMLChars[c]:
  237. fmt.Fprintf(&b, "\\x%02x", c)
  238. default:
  239. b.WriteRune(c)
  240. }
  241. }
  242. s = b.String()
  243. }
  244. return s
  245. }
  246. func setDefaults() {
  247. windowIndex[""] = App
  248. windowIndex["."] = App
  249. if goos == "windows" {
  250. wmWithdraw(App)
  251. }
  252. exitHandler = Command(func() {
  253. Destroy(App)
  254. for _, v := range Themes {
  255. v.Deactivate(nil)
  256. v.Finalize(nil)
  257. }
  258. })
  259. evalErr("option add *tearOff 0") // https://tkdocs.com/tutorial/menus.html
  260. NativeScaling = TkScaling()
  261. if s := os.Getenv(ScaleEnvVar); s != "" {
  262. if k, err := strconv.ParseFloat(s, 64); err == nil {
  263. TkScaling(min(max(k, 0.5), 5) * NativeScaling)
  264. }
  265. }
  266. if nm := os.Getenv(ThemeEnvVar); nm != "" {
  267. StyleThemeUse(nm)
  268. }
  269. wmTitle = filepath.Base(os.Args[0])
  270. wmTitle = strings.TrimSuffix(wmTitle, ".exe")
  271. App.WmTitle(wmTitle)
  272. x, y := -1, -1
  273. if os.Getenv("TK9_DEMO") == "1" {
  274. for i := 1; i < len(os.Args); i++ {
  275. s := os.Args[i]
  276. if !strings.HasPrefix(s, "+") {
  277. continue
  278. }
  279. a := strings.Split(s[1:], "+")
  280. if len(a) != 2 {
  281. continue
  282. }
  283. var err error
  284. if x, err = strconv.Atoi(a[0]); err != nil || x < 0 {
  285. x = -1
  286. break
  287. }
  288. if y, err = strconv.Atoi(a[1]); err != nil || y < 0 {
  289. y = -1
  290. }
  291. break
  292. }
  293. }
  294. App.Configure(Padx("4m"), Pady("3m"))
  295. if x >= 0 && y >= 0 {
  296. forcedX, forcedY = x, y
  297. }
  298. }
  299. // Window represents a Tk window/widget. It implements common widget methods.
  300. //
  301. // Window implements Opt. When a Window instance is used as an Opt, it provides
  302. // its path name.
  303. type Window struct {
  304. fpath string
  305. }
  306. func (w *Window) isWidget() {}
  307. // Widget is implemented by every *Window
  308. //
  309. // Widget implements Opt. When a Widget instance is used as an Opt, it provides
  310. // its path name.
  311. type Widget interface {
  312. isWidget()
  313. optionString(*Window) string
  314. }
  315. // String implements fmt.Stringer.
  316. func (w *Window) String() (r string) {
  317. if r = w.fpath; r == "" {
  318. r = "."
  319. }
  320. return r
  321. }
  322. func (w *Window) optionString(_ *Window) string {
  323. return w.String()
  324. }
  325. func (w *Window) split(options []Opt) (opts []Opt, tvs []textVarOpt, vs []*VariableOpt) {
  326. for _, v := range options {
  327. switch x := v.(type) {
  328. case textVarOpt:
  329. tvs = append(tvs, x)
  330. case *VariableOpt:
  331. vs = append(vs, x)
  332. default:
  333. opts = append(opts, x)
  334. }
  335. }
  336. return opts, tvs, vs
  337. }
  338. func (w *Window) newChild0(nm string) (rw *Window) {
  339. rw = &Window{fpath: fmt.Sprintf("%s.%s%v", w, nm, id.Add(1))}
  340. windowIndex[rw.fpath] = rw
  341. return rw
  342. }
  343. func (w *Window) newChild(nm string, options ...Opt) (rw *Window) {
  344. class := strings.Replace(nm, "ttk_", "ttk::", 1)
  345. nm = strings.Replace(nm, "ttk::", "t", 1)
  346. if c := nm[len(nm)-1]; c >= '0' && c <= '9' {
  347. nm += "_"
  348. }
  349. path := fmt.Sprintf("%s.%s%v", w, nm, id.Add(1))
  350. options, tvs, vs := w.split(options)
  351. rw = &Window{}
  352. code := fmt.Sprintf("%s %s %s", class, path, winCollect(rw, options...))
  353. var err error
  354. if rw.fpath, err = eval(code); err != nil {
  355. fail(fmt.Errorf("code=%s -> r=%s err=%v", code, rw.fpath, err))
  356. }
  357. if len(tvs) != 0 {
  358. rw.Configure(tvs[len(tvs)-1])
  359. }
  360. if len(vs) != 0 {
  361. rw.Configure(vs[len(vs)-1])
  362. }
  363. windowIndex[rw.fpath] = rw
  364. return rw
  365. }
  366. func evalErr(code string) (r string) {
  367. r, err := eval(code)
  368. if err != nil {
  369. fail(fmt.Errorf("code=%s -> r=%s err=%v", code, r, err))
  370. }
  371. return r
  372. }
  373. func fail(err error) {
  374. switch ErrorMode {
  375. default:
  376. fallthrough
  377. case PanicOnError:
  378. if dmesgs {
  379. dmesg("PANIC %v", err)
  380. }
  381. panic(err)
  382. case CollectErrors:
  383. Error = errors.Join(Error, err)
  384. }
  385. }
  386. func winCollect(w *Window, options ...Opt) string {
  387. var a []string
  388. for _, v := range options {
  389. a = append(a, v.optionString(w))
  390. }
  391. return strings.Join(a, " ")
  392. }
  393. func collectAny(options ...any) string {
  394. var a []string
  395. for _, v := range options {
  396. switch x := v.(type) {
  397. case Opt:
  398. a = append(a, x.optionString(nil))
  399. default:
  400. a = append(a, tclSafeString(fmt.Sprint(x)))
  401. }
  402. }
  403. return strings.Join(a, " ")
  404. }
  405. func collect(options ...Opt) string {
  406. var a []string
  407. for _, v := range options {
  408. a = append(a, v.optionString(nil))
  409. }
  410. return strings.Join(a, " ")
  411. }
  412. func collectOne(name string, options ...Opt) string {
  413. for _, v := range options {
  414. opt := v.optionString(nil)
  415. if strings.HasPrefix(opt, name) {
  416. return strings.TrimSpace(opt[len(name):])
  417. }
  418. }
  419. return ""
  420. }
  421. // Opts is a list of options. It implements Opt.
  422. type Opts []Opt
  423. func (o Opts) optionString(w *Window) string {
  424. return winCollect(w, []Opt(o)...)
  425. }
  426. // Opt represents an optional argument.
  427. type Opt interface {
  428. optionString(w *Window) string
  429. }
  430. type rawOption string
  431. func (s rawOption) optionString(w *Window) string {
  432. return string(s)
  433. }
  434. type stringOption string
  435. func (s stringOption) optionString(w *Window) string {
  436. return tclSafeString(string(s))
  437. }
  438. // EventHandler is the type used by call backs.
  439. type EventHandler func(*Event)
  440. // Event communicates information with an event handler. All handlers can use the Err field. Simple
  441. // handlers, like in
  442. //
  443. // Button(..., Command(func(e *Event) {...}))
  444. //
  445. // can use the 'W' field, if applicable. All other fields are valid only in
  446. // handlers bound using [Bind].
  447. type Event struct {
  448. // Event handlers should set Err on failure.
  449. Err error
  450. // Result can be optionally set by the handler. The field is returned by
  451. // certain methods, for example [TCheckbuttonWidget.Invoke].
  452. Result string
  453. // Event source, if any. This field is set when the event handler was
  454. // created.
  455. W *Window
  456. returnCode int // One of tcl_ok .. tcl_continue
  457. // The window to which the event was reported (the window field from
  458. // the event). Valid for all event types. This field is set when the
  459. // event is handled.
  460. EventWindow *Window
  461. // The keysym corresponding to the event, substituted as a textual string.
  462. // Valid only for Key and KeyRelease events.
  463. Keysym string
  464. // The number of the last client request processed by the server (the serial
  465. // field from the event). Valid for all event types.
  466. Serial int64
  467. // The width field from the event. Indicates the new or requested width of the
  468. // window. Valid only for Configure, ConfigureRequest, Create, ResizeRequest,
  469. // and Expose events.
  470. Width string
  471. // The height field from the event. Valid for the Configure, ConfigureRequest,
  472. // Create, ResizeRequest, and Expose events. Indicates the new or requested
  473. // height of the window.
  474. Height string
  475. // The x and y fields from the event. For Button, ButtonRelease, Motion, Key,
  476. // KeyRelease, and MouseWheel events, X and Y indicate the position of the
  477. // mouse pointer relative to the receiving window. For key events on the
  478. // Macintosh these are the coordinates of the mouse at the moment when an X11
  479. // KeyEvent is sent to Tk, which could be slightly later than the time of the
  480. // physical press or release. For Enter and Leave events, the position where
  481. // the mouse pointer crossed the window, relative to the receiving window. For
  482. // Configure and Create requests, the x and y coordinates of the window
  483. // relative to its parent window.
  484. X, Y int
  485. // The x_root and y_root fields from the event. If a virtual-root window
  486. // manager is being used then the substituted values are the corresponding
  487. // x-coordinate and y-coordinate in the virtual root. Valid only for Button,
  488. // ButtonRelease, Enter, Key, KeyRelease, Leave and Motion events. Same meaning
  489. // as X and Y, except relative to the (virtual) root window.
  490. XRoot, YRoot int
  491. // The delta value of a MouseWheel event. The delta value represents
  492. // the rotation units the mouse wheel has been moved. The sign of the
  493. // value represents the direction the mouse wheel was scrolled.
  494. Delta int
  495. // The state field from the event. For KeyPress, KeyRelease, ButtonPress,
  496. // ButtonRelease, Enter, Leave, and Motion events, it is a bit field.
  497. // Visibility events are not currently supported, and the value will be 0.
  498. State Modifier
  499. args []string
  500. }
  501. // Called from eventDispatcher. Arg1 is handler id, optionally followed by a
  502. // list of Bind substitution values.
  503. func newEvent(arg1 string) (id int, e *Event, err error) {
  504. e = &Event{returnCode: tcl_ok}
  505. a := strings.Fields(arg1)
  506. if len(a) == 0 {
  507. return -1, e, fmt.Errorf("internal error: missing handler ID")
  508. }
  509. if id, err = strconv.Atoi(a[0]); err != nil {
  510. return id, e, fmt.Errorf("newEvent: parsing event ID %q: %v", a[0], err)
  511. }
  512. for i, v := range a[1:] {
  513. switch i {
  514. case 0: // %#
  515. if e.Serial, err = strconv.ParseInt(v, 10, 64); err != nil {
  516. return id, e, fmt.Errorf("newEvent: parsing event serial %q: %v", v, err)
  517. }
  518. case 1: // %W
  519. e.EventWindow = windowIndex[v]
  520. case 2: // %K
  521. e.Keysym = v
  522. case 3: // %w
  523. e.Width = v
  524. case 4: // %h
  525. e.Height = v
  526. case 5: // %x
  527. e.X = atoi(v)
  528. case 6: // %y
  529. e.Y = atoi(v)
  530. case 7: // %X
  531. e.XRoot = atoi(v)
  532. case 8: // %Y
  533. e.YRoot = atoi(v)
  534. case 9: // %D
  535. e.Delta = atoi(v)
  536. case 10: // %s
  537. e.State = Modifier(atoi(v))
  538. }
  539. }
  540. return id, e, nil
  541. }
  542. func atoi(s string) int {
  543. if n, err := strconv.Atoi(s); err == nil {
  544. return n
  545. }
  546. return 0
  547. }
  548. // SetReturnCodeOK sets return code of 'e' to TCL_OK.
  549. func (e *Event) SetReturnCodeOK() {
  550. e.returnCode = tcl_ok
  551. }
  552. // SetReturnCodeError sets return code of 'e' to TCL_ERROR.
  553. func (e *Event) SetReturnCodeError() {
  554. e.returnCode = tcl_error
  555. }
  556. // SetReturnCodeReturn sets return code of 'e' to TCL_RETURN.
  557. func (e *Event) SetReturnCodeReturn() {
  558. e.returnCode = tcl_return
  559. }
  560. // SetReturnCodeBreak sets return code of 'e' to TCL_BREAK.
  561. func (e *Event) SetReturnCodeBreak() {
  562. e.returnCode = tcl_break
  563. }
  564. // SetReturnCodeContinue sets return code of 'e' to TCL_CONTINUE.
  565. func (e *Event) SetReturnCodeContinue() {
  566. e.returnCode = tcl_continue
  567. }
  568. // ScrollSet communicates events to scrollbars. Example:
  569. //
  570. // var scroll *TScrollbarWidget
  571. // // tcl: text .text -yscrollcommand ".scroll set"
  572. // t := Text(..., Yscrollcommand(func(e *Event) { e.ScrollSet(scroll) }))
  573. func (e *Event) ScrollSet(w Widget) {
  574. if len(e.args) > 1 {
  575. evalErr(fmt.Sprintf("%s set %s %s", w, e.args[0], e.args[1]))
  576. }
  577. }
  578. // Xview communicates events to views. Example:
  579. //
  580. // var scroll *TScrollbarWidget
  581. // t := Text(...)
  582. // // tcl: ttk::scrollbar .scroll -command ".text xview"
  583. // scroll = TScrollbar(Command(func(e *Event) { e.Xview(t)}))
  584. func (e *Event) Xview(w Widget) {
  585. if len(e.args) > 1 {
  586. evalErr(fmt.Sprintf("%s xview %s", w, strings.Join(e.args, " ")))
  587. }
  588. }
  589. // Yview communicates events to views. Example:
  590. //
  591. // var scroll *TScrollbarWidget
  592. // t := Text(...)
  593. // // tcl: ttk::scrollbar .scroll -command ".text yview"
  594. // scroll = TScrollbar(Command(func(e *Event) { e.Yview(t)}))
  595. func (e *Event) Yview(w Widget) {
  596. if len(e.args) > 1 {
  597. evalErr(fmt.Sprintf("%s yview %s", w, strings.Join(e.args, " ")))
  598. }
  599. }
  600. type eventHandler struct {
  601. callback func(*Event)
  602. id int32
  603. tcl string
  604. w *Window
  605. lateBind bool
  606. }
  607. func newEventHandler(option string, handler any) (r *eventHandler) {
  608. var callback func(*Event)
  609. switch x := handler.(type) {
  610. case EventHandler:
  611. callback = x
  612. case func(*Event):
  613. callback = x
  614. case func():
  615. callback = func(*Event) { x() }
  616. default:
  617. fail(fmt.Errorf("registering event handler: unsupported handler type: %T", handler))
  618. return nil
  619. }
  620. r = &eventHandler{
  621. callback: callback,
  622. id: id.Add(1),
  623. tcl: option,
  624. }
  625. handlers[r.id] = r
  626. return r
  627. }
  628. func (e *eventHandler) optionString(w *Window) string {
  629. if e == nil {
  630. return ""
  631. }
  632. e.w = w
  633. switch {
  634. case e.lateBind:
  635. return fmt.Sprintf("%s {eventDispatcher {%v %%# %%W %%K %%w %%h %%x %%y %%X %%Y %%D %%s}}", e.tcl, e.id)
  636. default:
  637. return fmt.Sprintf("%s {eventDispatcher %v}", e.tcl, e.id)
  638. }
  639. }
  640. func hexDigit(b byte) byte {
  641. if b <= 9 {
  642. return '0' + b
  643. }
  644. return 'a' + b - 10
  645. }
  646. func tclBinaryString(s string) string {
  647. var b strings.Builder
  648. for i := 0; i < len(s); i++ {
  649. v := s[i]
  650. b.WriteByte('\\')
  651. b.WriteByte('x')
  652. b.WriteByte(hexDigit(v >> 4))
  653. b.WriteByte(hexDigit(v & 15))
  654. }
  655. return b.String()
  656. }
  657. func tclBinaryBytes(s []byte) string {
  658. var b strings.Builder
  659. for _, v := range s {
  660. b.WriteByte('\\')
  661. b.WriteByte('x')
  662. b.WriteByte(hexDigit(v >> 4))
  663. b.WriteByte(hexDigit(v & 15))
  664. }
  665. return b.String()
  666. }
  667. var xpmSig = []byte("/* XPM */") // https://en.wikipedia.org/wiki/X_PixMap
  668. func optionString(v any) (r string) {
  669. switch x := v.(type) {
  670. case time.Duration:
  671. return fmt.Sprint(int64((x + time.Millisecond/2) / time.Millisecond))
  672. case []byte:
  673. switch {
  674. case bytes.HasPrefix(x, xpmSig):
  675. return tclSafeString(fmt.Sprintf("%s", v))
  676. default:
  677. return tclBinaryBytes(x)
  678. }
  679. case image.Image:
  680. var buf bytes.Buffer
  681. err := png.Encode(&buf, x)
  682. if err != nil {
  683. fail(err)
  684. return ""
  685. }
  686. return base64.StdEncoding.EncodeToString(buf.Bytes())
  687. case []FileType:
  688. var a []string
  689. for _, v := range x {
  690. a = append(a, fmt.Sprintf("{%s {%s} %s}", tclSafeString(v.TypeName), tclSafeStrings(v.Extensions...), v.MacType))
  691. }
  692. return fmt.Sprintf("{%s}", strings.Join(a, " "))
  693. default:
  694. return tclSafeString(fmt.Sprint(v))
  695. }
  696. }
  697. // bind — Arrange for X events to invoke functions
  698. //
  699. // # Description
  700. //
  701. // Bind tag options...
  702. //
  703. // The bind command associates commands with X events. If all three
  704. // arguments are specified, bind will arrange for script (a Tcl script called
  705. // the “binding script”) to be evaluated whenever the event(s) given by
  706. // sequence occur in the window(s) identified by tag. If script is prefixed
  707. // with a “+”, then it is appended to any existing binding for sequence;
  708. // otherwise script replaces any existing binding. If script is an empty string
  709. // then the current binding for sequence is destroyed, leaving sequence
  710. // unbound. In all of the cases where a script argument is provided, bind
  711. // returns an empty string.
  712. //
  713. // If sequence is specified without a script, then the script currently bound
  714. // to sequence is returned, or an empty string is returned if there is no
  715. // binding for sequence. If neither sequence nor script is specified, then the
  716. // return value is a list whose elements are all the sequences for which there
  717. // exist bindings for tag.
  718. //
  719. // The tag argument determines which window(s) the binding applies to. If tag
  720. // begins with a dot, as in .a.b.c, then it must be the path name for a window;
  721. // otherwise it may be an arbitrary string. Each window has an associated list
  722. // of tags, and a binding applies to a particular window if its tag is among
  723. // those specified for the window. Although the [Bindtags] command may be used to
  724. // assign an arbitrary set of binding tags to a window, the default binding
  725. // tags provide the following behavior:
  726. //
  727. // - If a tag is the name of an internal window the binding applies to that
  728. // window.
  729. // - If the tag is the name of a class of widgets, such as Button, the
  730. // binding applies to all widgets in that class.
  731. // - If the tag is the name of a toplevel window the binding applies to the
  732. // toplevel window and all its internal windows.
  733. // - If tag has the value all, the binding applies to all windows in the
  734. // application.
  735. //
  736. // Example usage in _examples/events.go.
  737. //
  738. // Additional information might be available at the [Tcl/Tk bind] page.
  739. //
  740. // [Tcl/Tk bind]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/bind.html
  741. func Bind(options ...any) {
  742. a := []string{"bind"}
  743. var w *Window
  744. for _, v := range options {
  745. switch x := v.(type) {
  746. case *Window:
  747. if w == nil {
  748. w = x
  749. }
  750. a = append(a, x.String())
  751. case *eventHandler:
  752. x.tcl = ""
  753. x.lateBind = true
  754. a = append(a, x.optionString(w))
  755. default:
  756. a = append(a, tclSafeStringBind(fmt.Sprint(x)))
  757. }
  758. }
  759. evalErr(strings.Join(a, " "))
  760. }
  761. // bindtags — Determine which bindings apply to a window, and order of evaluation
  762. //
  763. // # Description
  764. //
  765. // When a binding is created with the bind command, it is associated either
  766. // with a particular window such as .a.b.c, a class name such as Button, the
  767. // keyword all, or any other string. All of these forms are called binding
  768. // tags. Each window contains a list of binding tags that determine how events
  769. // are processed for the window. When an event occurs in a window, it is
  770. // applied to each of the window's tags in order: for each tag, the most
  771. // specific binding that matches the given tag and event is executed. See the
  772. // bind command for more information on the matching process.
  773. //
  774. // By default, each window has four binding tags consisting of the name of the
  775. // window, the window's class name, the name of the window's nearest toplevel
  776. // ancestor, and all, in that order. Toplevel windows have only three tags by
  777. // default, since the toplevel name is the same as that of the window. The
  778. // bindtags command allows the binding tags for a window to be read and
  779. // modified.
  780. //
  781. // If bindtags is invoked with only one argument, then the current set of
  782. // binding tags for window is returned as a list. If the tagList argument is
  783. // specified to bindtags, then it must be a proper list; the tags for window
  784. // are changed to the elements of the list. The elements of tagList may be
  785. // arbitrary strings; however, any tag starting with a dot is treated as the
  786. // name of a window; if no window by that name exists at the time an event is
  787. // processed, then the tag is ignored for that event. The order of the elements
  788. // in tagList determines the order in which binding scripts are executed in
  789. // response to events. For example, the command
  790. //
  791. // Bindtags(myBtn, "all", App, "Button", myBtn)
  792. //
  793. // reverses the order in which binding scripts will be evaluated for a button
  794. // myBtn so that all bindings are invoked first, following by bindings for
  795. // buttons (App), followed by class bindings, followed by bindings for
  796. // myBtn. If tagList is an empty list then the binding tags for window are
  797. // returned to the default state described above.
  798. //
  799. // The bindtags command may be used to introduce arbitrary additional binding
  800. // tags for a window, or to remove standard tags. For example, the command
  801. //
  802. // Bindtags(myBtn, myBtn, "TrickyButton", App, "all")
  803. //
  804. // replaces the Button tag for myBtn with TrickyButton. This means that the
  805. // default widget bindings for buttons, which are associated with the Button
  806. // tag, will no longer apply to myBtn, but any bindings associated with
  807. // TrickyButton (perhaps some new button behavior) will apply.
  808. //
  809. // Additional information might be available at the [Tcl/Tk bindtags] page.
  810. //
  811. // [Tcl/Tk bindtags]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/bindtags.html
  812. func Bindtags(w *Window, tagList ...any) (r []string) {
  813. switch len(tagList) {
  814. case 0:
  815. return parseList(evalErr(fmt.Sprintf("bindtags %s", w)))
  816. default:
  817. return parseList(evalErr(fmt.Sprintf("bindtags %s {%s}", w, tclSafeList(flat(tagList...)...))))
  818. }
  819. }
  820. // Img represents a Tk image.
  821. type Img struct {
  822. name string
  823. }
  824. // image — Create and manipulate images
  825. //
  826. // # Description
  827. //
  828. // Deletes 'm'. If there are instances of the image displayed in widgets, the
  829. // image will not actually be deleted until all of the instances are released.
  830. // However, the association between the instances and the image manager will be
  831. // dropped. Existing instances will retain their sizes but redisplay as empty
  832. // areas. If a deleted image is recreated with another call to image create,
  833. // the existing instances will use the new image.
  834. func (m *Img) Delete() {
  835. evalErr(fmt.Sprintf("image delete %s", m))
  836. }
  837. // String implements fmt.Stringer.
  838. func (m *Img) String() string {
  839. return m.optionString(nil)
  840. }
  841. func (m *Img) optionString(_ *Window) string {
  842. if m != nil {
  843. return m.name
  844. }
  845. return "img0" // does not exist
  846. }
  847. // Bitmap — Images that display two colors
  848. //
  849. // # Description
  850. //
  851. // A bitmap is an image whose pixels can display either of two colors or be
  852. // transparent. A bitmap image is defined by four things: a background color, a
  853. // foreground color, and two bitmaps, called the source and the mask. Each of
  854. // the bitmaps specifies 0/1 values for a rectangular array of pixels, and the
  855. // two bitmaps must have the same dimensions. For pixels where the mask is
  856. // zero, the image displays nothing, producing a transparent effect. For other
  857. // pixels, the image displays the foreground color if the source data is one
  858. // and the background color if the source data is zero.
  859. //
  860. // Additional information might be available at the [Tcl/Tk bitmap] page.
  861. //
  862. // - [Background] color
  863. //
  864. // Specifies a background color for the image in any of the standard ways
  865. // accepted by Tk. If this option is set to an empty string then the background
  866. // pixels will be transparent. This effect is achieved by using the source
  867. // bitmap as the mask bitmap, ignoring any -maskdata or -maskfile options.
  868. //
  869. // - [Data] string
  870. //
  871. // Specifies the contents of the source bitmap as a string. The string must
  872. // adhere to X11 bitmap format (e.g., as generated by the bitmap program). If
  873. // both the -data and -file options are specified, the -data option takes
  874. // precedence.
  875. //
  876. // - [File] name
  877. //
  878. // name gives the name of a file whose contents define the source bitmap. The
  879. // file must adhere to X11 bitmap format (e.g., as generated by the bitmap
  880. // program).
  881. //
  882. // - [Foreground] color
  883. //
  884. // Specifies a foreground color for the image in any of the standard ways
  885. // accepted by Tk.
  886. //
  887. // - [Maskdata] string
  888. //
  889. // Specifies the contents of the mask as a string. The string must adhere to
  890. // X11 bitmap format (e.g., as generated by the bitmap program). If both the
  891. // -maskdata and -maskfile options are specified, the -maskdata option takes
  892. // precedence.
  893. //
  894. // - [Maskfile] name
  895. //
  896. // name gives the name of a file whose contents define the mask. The file must
  897. // adhere to X11 bitmap format (e.g., as generated by the bitmap program).
  898. //
  899. // [Tcl/Tk bitmap]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/bitmap.html
  900. func NewBitmap(options ...Opt) *Img {
  901. nm := fmt.Sprintf("bmp%v", id.Add(1))
  902. code := fmt.Sprintf("image create bitmap %s %s", nm, collect(options...))
  903. r, err := eval(code)
  904. if err != nil {
  905. fail(fmt.Errorf("code=%s -> r=%s err=%v", code, r, err))
  906. return nil
  907. }
  908. return &Img{name: nm}
  909. }
  910. // Photo — Full-color images
  911. //
  912. // A photo is an image whose pixels can display any color with a varying degree
  913. // of transparency (the alpha channel). A photo image is stored internally in
  914. // full color (32 bits per pixel), and is displayed using dithering if
  915. // necessary. Image data for a photo image can be obtained from a file or a
  916. // string, or it can be supplied from C code through a procedural interface. A
  917. // photo image is (semi)transparent if the image data it was obtained from had
  918. // transparency information. In regions where no image data has been supplied,
  919. // it is fully transparent. Transparency may also be modified with the
  920. // transparency set subcommand.
  921. //
  922. // # Supported image formats
  923. //
  924. // - BMP
  925. // - GIF
  926. // - ICO
  927. // - JPEG
  928. // - PCX
  929. // - PNG
  930. // - PPM
  931. // - SVG
  932. // - TGA
  933. // - TIFF
  934. // - XBM
  935. // - XMP
  936. //
  937. // # Photo Options
  938. //
  939. // - [Data] string
  940. //
  941. // Specifies the contents of the image as a string. The string should contain
  942. // binary data or, for some formats, base64-encoded data (this is currently
  943. // guaranteed to be supported for PNG and GIF images). The format of the string
  944. // must be one of those for which there is an image file format handler that
  945. // will accept string data. If both the -data and -file options are specified,
  946. // the -file option takes precedence.
  947. //
  948. // - [Format] format-name
  949. //
  950. // Specifies the name of the file format for the data specified with the -data
  951. // or -file option.
  952. //
  953. // - [File] name
  954. //
  955. // name gives the name of a file that is to be read to supply data for the
  956. // photo image. The file format must be one of those for which there is an
  957. // image file format handler that can read data.
  958. //
  959. // - [Gamma] value
  960. //
  961. // Specifies that the colors allocated for displaying this image in a window
  962. // should be corrected for a non-linear display with the specified gamma
  963. // exponent value. (The intensity produced by most CRT displays is a power
  964. // function of the input value, to a good approximation; gamma is the exponent
  965. // and is typically around 2). The value specified must be greater than zero.
  966. // The default value is one (no correction). In general, values greater than
  967. // one will make the image lighter, and values less than one will make it
  968. // darker.
  969. //
  970. // - [Height] number
  971. //
  972. // Specifies the height of the image, in pixels. This option is useful
  973. // primarily in situations where the user wishes to build up the contents of
  974. // the image piece by piece. A value of zero (the default) allows the image to
  975. // expand or shrink vertically to fit the data stored in it.
  976. //
  977. // - [Palette] palette-spec
  978. //
  979. // Specifies the resolution of the color cube to be allocated for displaying
  980. // this image, and thus the number of colors used from the colormaps of the
  981. // windows where it is displayed. The palette-spec string may be either a
  982. // single decimal number, specifying the number of shades of gray to use, or
  983. // three decimal numbers separated by slashes (/), specifying the number of
  984. // shades of red, green and blue to use, respectively. If the first form (a
  985. // single number) is used, the image will be displayed in monochrome (i.e.,
  986. // grayscale).
  987. //
  988. // - [Width] number
  989. //
  990. // Specifies the width of the image, in pixels. This option is useful primarily
  991. // in situations where the user wishes to build up the contents of the image
  992. // piece by piece. A value of zero (the default) allows the image to expand or
  993. // shrink horizontally to fit the data stored in it.
  994. //
  995. // Additional information might be available at the [Tcl/Tk photo] page.
  996. //
  997. // # Format("bmp") additional options
  998. //
  999. // In addition the value of option [Format] is treated as a list and may contain
  1000. // any of the special options listed below.
  1001. //
  1002. // - -verbose bool
  1003. //
  1004. // This option is supported for reading and writing. Available since
  1005. // version 2.0.
  1006. //
  1007. // If set to true, additional information about the read or written image
  1008. // is printed to stdout. Default is false.
  1009. //
  1010. // - -resolution xres ?yres?
  1011. //
  1012. // This option is supported for writing only. Available since version 2.0.
  1013. // An incompatible version of this option was introduced in version 1.4.1.
  1014. //
  1015. // Set the resolution values of the written image file. If yres is not
  1016. // specified, it is set to the value of xres.
  1017. //
  1018. // If option is not specified, the DPI and aspect values of the metadata
  1019. // dictionary are written. If no metadata values are available, no
  1020. // resolution values are written.
  1021. //
  1022. // - -xresolution xres
  1023. //
  1024. // This option is supported for writing only. Available since version 2.0.
  1025. //
  1026. // Set the horizontal resolution value of the written image file.
  1027. //
  1028. // - -yresolution yres
  1029. //
  1030. // This option is supported for writing only. Available since version 2.0.
  1031. //
  1032. // Set the vertical resolution value of the written image file.
  1033. //
  1034. // Additional information might be available at the [tkImg-bmp] page.
  1035. //
  1036. // # Format("ico") additional options
  1037. //
  1038. // In addition the value of option [Format] is treated as a list and may contain
  1039. // any of the special options listed below.
  1040. //
  1041. // - -verbose bool
  1042. //
  1043. // This option is supported for reading and writing. Available since version
  1044. // 1.3.
  1045. //
  1046. // If set to true, additional information about the read or written image is
  1047. // printed to stdout. Default is false.
  1048. //
  1049. // - -index integer
  1050. //
  1051. // This option is supported for reading only. Available since version 1.3.
  1052. //
  1053. // Read the page at specified index. The first page is at index 0. Default is
  1054. // 0.
  1055. //
  1056. // Additional information might be available at the [tkImg-ico] page.
  1057. //
  1058. // # Format("jpeg") additional options
  1059. //
  1060. // In addition the value of option [Format] is treated as a list and may contain
  1061. // any of the special options listed below.
  1062. //
  1063. // - -verbose bool
  1064. //
  1065. // This option is supported for reading and writing. Available since version
  1066. // 2.0.
  1067. //
  1068. // If set to true, additional information about the read or written image is
  1069. // printed to stdout. Default is false.
  1070. //
  1071. // - -fast
  1072. //
  1073. // This option is supported for reading only. Available since version
  1074. // 1.2.4.
  1075. //
  1076. // If specified, it activates a processing mode which is fast, but
  1077. // provides only low-quality information.
  1078. //
  1079. // - -grayscale
  1080. //
  1081. // This option is supported for reading and writing. Available since
  1082. // version 1.2.4.
  1083. //
  1084. // Usage of this option forces incoming images to grayscale and written
  1085. // images will be monochrome.
  1086. //
  1087. // - -optimize
  1088. //
  1089. // This option is supported for writing only. Available since version
  1090. // 1.2.4.
  1091. //
  1092. // If specified, it causes the writer to optimize the Huffman table used
  1093. // to encode the JPEG coefficients.
  1094. //
  1095. // - -progressive
  1096. //
  1097. // This option is supported for writing only. Available since version
  1098. // 1.2.4.
  1099. //
  1100. // If specified, it causes the creation of a progressive JPEG file.
  1101. //
  1102. // - -quality n
  1103. //
  1104. // This option is supported for writing only. Available since version
  1105. // 1.2.4.
  1106. //
  1107. // It specifies the compression level as a quality percentage. The higher the
  1108. // quality, the less the compression. The nominal range for n is 0...100.
  1109. // Useful values are in the range 5...95. The default value is 75.
  1110. //
  1111. // - -smooth n
  1112. //
  1113. // This option is supported for writing only. Available since version
  1114. // 1.2.4.
  1115. //
  1116. // When used the writer will smooth the image before performing the
  1117. // compression. Values in the 10...30 are usually enough. The default is
  1118. // 0, i.e no smoothing.
  1119. //
  1120. // - -resolution xres ?yres?
  1121. //
  1122. // This option is supported for writing only. Available since version 2.0.
  1123. //
  1124. // Set the resolution values of the written image file. If yres is not
  1125. // specified, it is set to the value of xres.
  1126. //
  1127. // If option is not specified, the DPI and aspect values of the metadata
  1128. // dictionary are written. If no metadata values are available, no
  1129. // resolution values are written.
  1130. //
  1131. // - -xresolution xres
  1132. //
  1133. // This option is supported for writing only. Available since version 2.0.
  1134. //
  1135. // Set the horizontal resolution value of the written image file.
  1136. //
  1137. // - -yresolution yres
  1138. //
  1139. // This option is supported for writing only. Available since version 2.0.
  1140. //
  1141. // Set the vertical resolution value of the written image file.
  1142. //
  1143. // Additional information might be available at the [tkImg-jpeg] page.
  1144. //
  1145. // # Format("pcx") additional options
  1146. //
  1147. // In addition the value of option [Format] is treated as a list and may contain
  1148. // any of the special options listed below.
  1149. //
  1150. // - -verbose bool
  1151. //
  1152. // This option is supported for reading and writing. Available since
  1153. // version 1.3.
  1154. //
  1155. // If set to true, additional information about the read or written image
  1156. // is printed to stdout. Default is false.
  1157. //
  1158. // - -compression string
  1159. //
  1160. // This option is supported for writing only. Available since version 1.3.
  1161. //
  1162. // Set the compression mode to either none or rle. Default is rle.
  1163. //
  1164. // - -resolution xres ?yres?
  1165. //
  1166. // This option is supported for writing only. Available since version 2.0.
  1167. //
  1168. // Set the resolution values of the written image file. If yres is not
  1169. // specified, it is set to the value of xres.
  1170. //
  1171. // If option is not specified, the DPI and aspect values of the metadata
  1172. // dictionary are written. If no metadata values are available, no
  1173. // resolution values are written.
  1174. //
  1175. // - -xresolution xres
  1176. //
  1177. // This option is supported for writing only. Available since version 2.0.
  1178. //
  1179. // Set the horizontal resolution value of the written image file.
  1180. //
  1181. // - -yresolution yres
  1182. //
  1183. // This option is supported for writing only. Available since version 2.0.
  1184. //
  1185. // Set the vertical resolution value of the written image file.
  1186. //
  1187. // Additional information might be available at the [tkImg-pcx] page.
  1188. //
  1189. // # Format("png") additional options
  1190. //
  1191. // In addition the value of option [Format] is treated as a list and may contain
  1192. // any of the special options listed below.
  1193. //
  1194. // - -verbose bool
  1195. //
  1196. // This option is supported for reading and writing. Available since
  1197. // version 1.4.6.
  1198. //
  1199. // If set to true, additional information about the read or written image
  1200. // is printed to stdout. Default is false.
  1201. //
  1202. // - -alpha double
  1203. //
  1204. // This option is supported for reading only. Available since version
  1205. // 1.4.2.
  1206. //
  1207. // An additional alpha filtering value for the overall image, which allows
  1208. // the background on which the image is displayed to show through. This
  1209. // usually also has the effect of desaturating the image. The alpha value
  1210. // must be between 0.0 and 1.0. Specifying an alpha value, overrides the
  1211. // setting of the -withalpha flag, i.e. reading a file which has no alpha
  1212. // channel (Grayscale, RGB) will add an alpha channel to the image
  1213. // independent of the -withalpha flag setting.
  1214. //
  1215. // - -gamma double
  1216. //
  1217. // This option is supported for reading only. Available since version
  1218. // 1.4.6.
  1219. //
  1220. // Use the specified gamma value when reading an image. This option
  1221. // overwrites gamma values specified in the file. If this option is not
  1222. // specified and no gamma value is in the file, a default value of 1.0 is
  1223. // used.
  1224. //
  1225. // - -withalpha bool
  1226. //
  1227. // This option is supported for reading and writing. Available since
  1228. // version 1.4.1.
  1229. //
  1230. // If set to false, an alpha channel is ignored during reading or writing.
  1231. // Default is true.
  1232. //
  1233. // Note: This option was named -matte in previous versions and is still
  1234. // recognized.
  1235. //
  1236. // - -resolution xres ?yres?
  1237. //
  1238. // This option is supported for writing only. Available since version 2.0.
  1239. //
  1240. // Set the resolution values of the written image file. If yres is not
  1241. // specified, it is set to the value of xres.
  1242. //
  1243. // If option is not specified, the DPI and aspect values of the metadata
  1244. // dictionary are written. If no metadata values are available, no
  1245. // resolution values are written.
  1246. //
  1247. // - -xresolution xres
  1248. //
  1249. // This option is supported for writing only. Available since version 2.0.
  1250. //
  1251. // Set the horizontal resolution value of the written image file.
  1252. //
  1253. // - -yresolution yres
  1254. //
  1255. // This option is supported for writing only. Available since version 2.0.
  1256. //
  1257. // Set the vertical resolution value of the written image file.
  1258. //
  1259. // - -tag key value
  1260. //
  1261. // This option is supported for writing only. Available since version 2.0.
  1262. //
  1263. // Each key-value pair will be written as a named text chunk where the key
  1264. // provides the name of the chunk and the value its contents. Currently the
  1265. // maximum number of -tag specifications are 10.
  1266. //
  1267. // Additional information might be available at the [tkImg-png] page.
  1268. //
  1269. // # Format("ppm") additional options
  1270. //
  1271. // In addition the value of option [Format] is treated as a list and may contain
  1272. // any of the special options listed below.
  1273. //
  1274. // - -verbose bool
  1275. //
  1276. // This option is supported for reading and writing. Available since
  1277. // version 1.4.0.
  1278. //
  1279. // If set to true, additional information about the read or written image
  1280. // is printed to stdout. Default is false.
  1281. //
  1282. // - -scanorder string
  1283. //
  1284. // This option is supported for reading only. Available since version
  1285. // 1.4.0.
  1286. //
  1287. // Specify the scanline order of the input image. Possible values: TopDown
  1288. // or BottomUp. Default is TopDown.
  1289. //
  1290. // - -min double
  1291. //
  1292. // This option is supported for reading only. Available since version
  1293. // 1.4.0.
  1294. //
  1295. // Specify the minimum pixel value to be used for mapping 16-bit input data
  1296. // to 8-bit image values. If not specified or negative, the minimum value
  1297. // found in the image data.
  1298. //
  1299. // - -max float
  1300. //
  1301. // This option is supported for reading only. Available since version
  1302. // 1.4.0.
  1303. //
  1304. // Specify the maximum pixel value to be used for mapping 16-bit input data
  1305. // to 8-bit image values. If not specified or negative, the maximum value
  1306. // found in the image data.
  1307. //
  1308. // - -gamma double
  1309. //
  1310. // This option is supported for reading only. Available since version
  1311. // 1.4.0.
  1312. //
  1313. // Specify a gamma correction to be applied when mapping 16-bit input data
  1314. // to 8-bit image values. Default is 1.0.
  1315. //
  1316. // - -ascii bool
  1317. //
  1318. // This option is supported for writing only. Available since version
  1319. // 1.4.0.
  1320. //
  1321. // If set to true, the file is written in PPM 8-bit ASCII format (P3).
  1322. // Default is false, i.e. write in PPM 8-bit binary format (P6).
  1323. //
  1324. // Additional information might be available at the [tkImg-ppm] page.
  1325. //
  1326. // # Format("tga") additional options
  1327. //
  1328. // In addition the value of option [Format] is treated as a list and may contain
  1329. // any of the special options listed below.
  1330. //
  1331. // - -verbose bool
  1332. //
  1333. // This option is supported for reading and writing. Available since
  1334. // version 1.3.
  1335. //
  1336. // If set to true, additional information about the read or written image
  1337. // is printed to stdout. Default is false.
  1338. //
  1339. // - -withalpha bool
  1340. //
  1341. // This option is supported for reading and writing. Available since
  1342. // version 1.3.
  1343. //
  1344. // If set to false, an alpha channel is ignored during reading or writing.
  1345. // Default is true.
  1346. //
  1347. // Note: This option was named -matte in previous versions and is still
  1348. // recognized.
  1349. //
  1350. // - -compression string
  1351. //
  1352. // This option is supported for writing only. Available since version 1.3.
  1353. //
  1354. // Set the compression mode to either none or rle. Default is rle.
  1355. //
  1356. // Additional information might be available at the [tkImg-tga] page.
  1357. //
  1358. // # Format("tiff") additional options
  1359. //
  1360. // In addition the value of option [Format] is treated as a list and may contain
  1361. // any of the special options listed below.
  1362. //
  1363. // - -verbose bool
  1364. //
  1365. // This option is supported for reading and writing. Available since
  1366. // version 2.0.
  1367. //
  1368. // If set to true, additional information about the read or written image
  1369. // is printed to stdout. Default is false.
  1370. //
  1371. // - -index integer
  1372. //
  1373. // This option is supported for reading only. Available since version
  1374. // 1.4.0.
  1375. //
  1376. // Read the page at specified index. The first page is at index 0. Default
  1377. // is 0.
  1378. //
  1379. // - -compression string
  1380. //
  1381. // This option is supported for writing only. Available since version
  1382. // 1.2.4.
  1383. //
  1384. // Set the compression mode to either none, jpeg, packbits, or deflate.
  1385. // Default is none.
  1386. //
  1387. // - -byteorder string
  1388. //
  1389. // This option is supported for writing only. Available since version
  1390. // 1.2.4.
  1391. //
  1392. // Set the byteorder to either none, bigendian, littleendian, network or
  1393. // smallendian. Default is none.
  1394. //
  1395. // The values bigendian and network are aliases of each other, as are
  1396. // littleendian and smallendian.
  1397. //
  1398. // - -resolution xres ?yres?
  1399. //
  1400. // This option is supported for writing only. Available since version 2.0.
  1401. //
  1402. // Set the resolution values of the written image file. If yres is not
  1403. // specified, it is set to the value of xres.
  1404. //
  1405. // If option is not specified, the DPI and aspect values of the metadata
  1406. // dictionary are written. If no metadata values are available, no
  1407. // resolution values are written.
  1408. //
  1409. // - -xresolution xres
  1410. //
  1411. // This option is supported for writing only. Available since version 2.0.
  1412. //
  1413. // Set the horizontal resolution value of the written image file.
  1414. //
  1415. // - -yresolution yres
  1416. //
  1417. // This option is supported for writing only. Available since version 2.0.
  1418. //
  1419. // Set the vertical resolution value of the written image file.
  1420. //
  1421. // Additional information might be available at the [tkImg-tiff] page.
  1422. //
  1423. // # Format("xbm") additional options
  1424. //
  1425. // In addition the value of option [Format] is treated as a list and may contain
  1426. // any of the special options listed below.
  1427. //
  1428. // - -verbose bool
  1429. //
  1430. // This option is supported for reading and writing. Available since
  1431. // version 2.0.
  1432. //
  1433. // If set to true, additional information about the read or written image
  1434. // is printed to stdout. Default is false.
  1435. //
  1436. // - -foreground string
  1437. //
  1438. // This option is supported for reading only. Available since version
  1439. // 1.4.15.
  1440. //
  1441. // Set the foreground color of the bitmap. Default value is black. The
  1442. // color string may be given in a format as accepted by Tk_GetColor.
  1443. //
  1444. // - -background string
  1445. //
  1446. // This option is supported for reading only. Available since version
  1447. // 1.4.15.
  1448. //
  1449. // Set the background color of the bitmap. Default value is transparent.
  1450. // The color string may be given in a format as accepted by Tk_GetColor.
  1451. //
  1452. // Additional information might be available at the [tkImg-xbm] page.
  1453. //
  1454. // # Format("xpm") additional options
  1455. //
  1456. // In addition the value of option [Format] is treated as a list and may contain
  1457. // any of the special options listed below.
  1458. //
  1459. // - -verbose bool
  1460. //
  1461. // This option is supported for reading and writing. Available since
  1462. // version 2.0.
  1463. //
  1464. // If set to true, additional information about the read or written image
  1465. // is printed to stdout. Default is false.
  1466. //
  1467. // Additional information might be available at the [tkImg-xpm] page.
  1468. //
  1469. // [Tcl/Tk photo]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/photo.html
  1470. // [tkImg-bmp]: https://tkimg.sourceforge.net/RefMan/files/img-bmp.html
  1471. // [tkImg-ico]: https://tkimg.sourceforge.net/RefMan/files/img-ico.html
  1472. // [tkImg-jpeg]: https://tkimg.sourceforge.net/RefMan/files/img-jpeg.html
  1473. // [tkImg-pcx]: https://tkimg.sourceforge.net/RefMan/files/img-pcx.html
  1474. // [tkImg-png]: https://tkimg.sourceforge.net/RefMan/files/img-png.html
  1475. // [tkImg-ppm]: https://tkimg.sourceforge.net/RefMan/files/img-ppm.html
  1476. // [tkImg-tga]: https://tkimg.sourceforge.net/RefMan/files/img-tga.html
  1477. // [tkImg-tiff]: https://tkimg.sourceforge.net/RefMan/files/img-tiff.html
  1478. // [tkImg-xbm]: https://tkimg.sourceforge.net/RefMan/files/img-xbm.html
  1479. // [tkImg-xpm]: https://tkimg.sourceforge.net/RefMan/files/img-xmp.html
  1480. func NewPhoto(options ...Opt) *Img {
  1481. nm := fmt.Sprintf("img%v", id.Add(1))
  1482. code := fmt.Sprintf("image create photo %s %s", nm, collect(options...))
  1483. r, err := eval(code)
  1484. if err != nil {
  1485. fail(fmt.Errorf("code=%s -> r=%s err=%v", code, r, err))
  1486. return nil
  1487. }
  1488. return &Img{name: nm}
  1489. }
  1490. // Width — Get the configured option value.
  1491. //
  1492. // Additional information might be available at the [Tcl/Tk photo] page.
  1493. //
  1494. // [Tcl/Tk photo]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/photo.html
  1495. func (m *Img) Width() string {
  1496. return evalErr(fmt.Sprintf(`image width %s`, m))
  1497. }
  1498. // Height — Get the configured option value.
  1499. //
  1500. // Additional information might be available at the [Tcl/Tk photo] page.
  1501. //
  1502. // [Tcl/Tk photo]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/photo.html
  1503. func (m *Img) Height() string {
  1504. return evalErr(fmt.Sprintf(`image height %s`, m))
  1505. }
  1506. // // Returns photo data.
  1507. // //
  1508. // // Additional information might be available at the [Tcl/Tk photo] page.
  1509. // //
  1510. // // [Tcl/Tk photo]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/photo.html
  1511. // func (m *Img) Data(options ...Opt) []byte {
  1512. // s := evalErr(fmt.Sprintf("%s data %s", collect(options...)))
  1513. // panic(todo("%q", s))
  1514. // }
  1515. // photo — Full-color images
  1516. //
  1517. // Copies a region from the image called sourceImage (which must be a photo
  1518. // image) to the image called imageName, possibly with pixel zooming and/or
  1519. // subsampling. If no options are specified, this command copies the whole of
  1520. // sourceImage into imageName, starting at coordinates (0,0) in imageName.
  1521. //
  1522. // The following options may be specified:
  1523. //
  1524. // - [From] x1 y1 x2 y2
  1525. //
  1526. // Specifies a rectangular sub-region of the source image to be copied. (x1,y1)
  1527. // and (x2,y2) specify diagonally opposite corners of the rectangle. If x2 and
  1528. // y2 are not specified, the default value is the bottom-right corner of the
  1529. // source image. The pixels copied will include the left and top edges of the
  1530. // specified rectangle but not the bottom or right edges. If the -from option
  1531. // is not given, the default is the whole source image.
  1532. //
  1533. // - [To] x1 y1 x2 y2
  1534. //
  1535. // Specifies a rectangular sub-region of the destination image to be affected.
  1536. // (x1,y1) and (x2,y2) specify diagonally opposite corners of the rectangle. If
  1537. // x2 and y2 are not specified, the default value is (x1,y1) plus the size of
  1538. // the source region (after subsampling and zooming, if specified). If x2 and
  1539. // y2 are specified, the source region will be replicated if necessary to fill
  1540. // the destination region in a tiled fashion.
  1541. //
  1542. // The function returns 'm'.
  1543. //
  1544. // Additional information might be available at the [Tcl/Tk photo] page.
  1545. //
  1546. // [Tcl/Tk photo]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/photo.html
  1547. func (m *Img) Copy(src *Img, options ...Opt) (r *Img) {
  1548. evalErr(fmt.Sprintf("%s copy %s %s", m, src, collect(options...)))
  1549. return m
  1550. }
  1551. // From option.
  1552. //
  1553. // Known uses:
  1554. // - [Img.Copy]
  1555. // - [Scale] (widget specific)
  1556. // - [Spinbox] (widget specific)
  1557. // - [TScale] (widget specific)
  1558. // - [TSpinbox] (widget specific)
  1559. func From(val ...any) Opt {
  1560. return rawOption(fmt.Sprintf(`-from %s`, collectAny(val...)))
  1561. }
  1562. // To option.
  1563. //
  1564. // Known uses:
  1565. // - [Img.Copy]
  1566. // - [Scale] (widget specific)
  1567. // - [Spinbox] (widget specific)
  1568. // - [TScale] (widget specific)
  1569. // - [TSpinbox] (widget specific)
  1570. func To(val ...any) Opt {
  1571. return rawOption(fmt.Sprintf(`-to %s`, collectAny(val...)))
  1572. }
  1573. // Graph — use gnuplot to draw on a photo. Graph returns 'm'
  1574. //
  1575. // The 'script' argument is passed to a gnuplot executable, which must be
  1576. // installed on the machine. See the [gnuplot site] for documentation about
  1577. // producing graphs. The script must not use the 'set term <device>' command.
  1578. //
  1579. // The content of 'm' is replaced, including its internal name.
  1580. //
  1581. // [gnuplot site]: http://www.gnuplot.info/
  1582. func (m *Img) Graph(script string) *Img {
  1583. switch {
  1584. case strings.HasPrefix(m.name, "img"):
  1585. w, h := m.Width(), m.Height()
  1586. script = fmt.Sprintf("set terminal pngcairo size %s, %s\n%s", w, h, script)
  1587. out, err := gnuplot(script)
  1588. if err != nil {
  1589. fail(fmt.Errorf("plot: executing script: %s", err))
  1590. break
  1591. }
  1592. *m = *NewPhoto(Width(w), Height(h), Data(out))
  1593. default:
  1594. fail(fmt.Errorf("plot: %s is not a photo", m))
  1595. }
  1596. return m
  1597. }
  1598. // Destroy — Destroy one or more windows
  1599. //
  1600. // # Description
  1601. //
  1602. // This command deletes the windows given by the window arguments, plus all of
  1603. // their descendants. If a window “.” (App) is deleted then all windows will be
  1604. // destroyed and the application will (normally) exit. The windows are
  1605. // destroyed in order, and if an error occurs in destroying a window the
  1606. // command aborts without destroying the remaining windows. No error is
  1607. // returned if window does not exist.
  1608. func Destroy(options ...Opt) {
  1609. evalErr(fmt.Sprintf("destroy %s", collect(options...)))
  1610. }
  1611. // Pack — Geometry manager that packs around edges of cavity
  1612. //
  1613. // # Description
  1614. //
  1615. // The options consist of one or more content windows followed
  1616. // by options that specify how to manage the content. See THE PACKER
  1617. // ALGORITHM for details on how the options are used by the packer.
  1618. //
  1619. // The first argument must be a *Window.
  1620. //
  1621. // The following options are supported:
  1622. //
  1623. // - [After] other
  1624. //
  1625. // Other must the name of another window. Use its container as the container
  1626. // for the content, and insert the content just after other in the packing
  1627. // order.
  1628. //
  1629. // - [Anchor] anchor
  1630. //
  1631. // Anchor must be a valid anchor position such as n or sw; it specifies where
  1632. // to position each content in its parcel. Defaults to center.
  1633. //
  1634. // - [Before] other
  1635. //
  1636. // Other must the name of another window. Use its container as the container
  1637. // for the content, and insert the content just before other in the packing
  1638. // order.
  1639. //
  1640. // - [Expand] boolean
  1641. //
  1642. // Specifies whether the content should be expanded to consume extra space in
  1643. // their container. Boolean may have any proper boolean value, such as 1 or no.
  1644. // Defaults to 0.
  1645. //
  1646. // - [Fill] style
  1647. //
  1648. // If a content's parcel is larger than its requested dimensions, this option
  1649. // may be used to stretch the content. Style must have one of the following
  1650. // values:
  1651. //
  1652. // - "none" - Give the content its requested dimensions plus any internal
  1653. // padding requested with -ipadx or -ipady. This is the default.
  1654. // - "x" - Stretch the content horizontally to fill the entire width of its
  1655. // parcel (except leave external padding as specified by -padx).
  1656. // - "y" - Stretch the content vertically to fill the entire height of its parcel
  1657. // (except leave external padding as specified by -pady).
  1658. // - "both": Stretch the content both horizontally and vertically.
  1659. //
  1660. // .
  1661. //
  1662. // - [In] container
  1663. //
  1664. // Insert the window at the end of the packing order for the container window
  1665. // given by container.
  1666. //
  1667. // - [Ipadx] amount
  1668. //
  1669. // Amount specifies how much horizontal internal padding to leave on each side
  1670. // of the content. Amount must be a valid screen distance, such as 2 or .5c. It
  1671. // defaults to 0.
  1672. //
  1673. // - [Ipady] amount
  1674. //
  1675. // Amount specifies how much vertical internal padding to leave on each side of
  1676. // the content. Amount defaults to 0.
  1677. //
  1678. // - [Padx] amount
  1679. //
  1680. // Amount specifies how much horizontal external padding to leave on each side
  1681. // of the content. Amount may be a list of two values to specify padding for
  1682. // left and right separately. Amount defaults to 0.
  1683. //
  1684. // - [Pady] amount
  1685. //
  1686. // Amount specifies how much vertical external padding to leave on each side of
  1687. // the content. Amount may be a list of two values to specify padding for top
  1688. // and bottom separately. Amount defaults to 0.
  1689. //
  1690. // - [Side] side
  1691. //
  1692. // Specifies which side of the container the content will be packed against.
  1693. // Must be "left", "right", "top", or "bottom". Defaults to top.
  1694. //
  1695. // If no -in, -after or -before option is specified then each of the content
  1696. // will be inserted at the end of the packing list for its parent unless it is
  1697. // already managed by the packer (in which case it will be left where it is).
  1698. // If one of these options is specified then all the content will be inserted
  1699. // at the specified point. If any of the content are already managed by the
  1700. // geometry manager then any unspecified options for them retain their previous
  1701. // values rather than receiving default values.
  1702. //
  1703. // Additional information might be available at the [Tcl/Tk pack] page.
  1704. //
  1705. // [Tcl/Tk pack]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/pack.html
  1706. func Pack(options ...Opt) {
  1707. evalErr(fmt.Sprintf("pack %s", collect(options...)))
  1708. }
  1709. // SetResizable — Enable/disable window resizing
  1710. //
  1711. // # Description
  1712. //
  1713. // This command controls whether or not the user may interactively resize a
  1714. // top-level window. If resizing is disabled, then the window's size will be
  1715. // the size from the most recent interactive resize or wm geometry command. If
  1716. // there has been no such operation then the window's natural size will be
  1717. // used.
  1718. //
  1719. // More information might be available at the [Tcl/Tk wm] page.
  1720. //
  1721. // [Tcl/Tk wm]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/wm.html
  1722. func (w *Window) SetResizable(width, height bool) {
  1723. evalErr(fmt.Sprintf("wm resizable %s %v %v", w, width, height))
  1724. }
  1725. // Wait — Wait for a window to be destroyed
  1726. //
  1727. // # Description
  1728. //
  1729. // Wait command waits for 'w' to be destroyed. This is typically used to wait
  1730. // for a user to finish interacting with a dialog box before using the result
  1731. // of that interaction.
  1732. //
  1733. // While the Wwait command is waiting it processes events in the normal
  1734. // fashion, so the application will continue to respond to user interactions.
  1735. // If an event handler invokes Wait again, the nested call to Wait must
  1736. // complete before the outer call can complete.
  1737. func (w *Window) Wait() {
  1738. if isBuilder && testHookWait != "" {
  1739. TclAfterIdle(Command(func() {
  1740. fmt.Println(testHookWait)
  1741. }))
  1742. }
  1743. if w == App {
  1744. switch {
  1745. case os.Getenv("TK9_VNC") == "1":
  1746. autocenterDisabled = true
  1747. WmGeometry(App, fmt.Sprintf("%sx%s+0+0", os.Getenv("TK9_VNC_WIDTH"), os.Getenv("TK9_VNC_HEIGHT")))
  1748. case forcedX >= 0 && forcedY >= 0: // Behind TK9_DEMO=1.
  1749. evalErr(fmt.Sprintf("wm geometry . +%v+%v", forcedX, forcedY)) //TODO add API func
  1750. forcedX, forcedY = -1, -1 // Apply only the first time.
  1751. default:
  1752. if goos == "windows" {
  1753. if !appWithdrawn && !appIconified {
  1754. WmDeiconify(App)
  1755. }
  1756. }
  1757. if !autocenterDisabled {
  1758. autocenterDisabled = true
  1759. w.Center()
  1760. }
  1761. }
  1762. if !appIconPhotoDone {
  1763. App.IconPhoto(NewPhoto(Data(icon)))
  1764. }
  1765. }
  1766. evalErr(fmt.Sprintf("tkwait window %s", w))
  1767. }
  1768. // WaitVisibility — Wait for a window to change visibility
  1769. //
  1770. // # Description
  1771. //
  1772. // WaitVisibility command waits for a change in w's visibility state (as
  1773. // indicated by the arrival of a VisibilityNotify event). This form is
  1774. // typically used to wait for a newly-created window to appear on the screen
  1775. // before taking some action.
  1776. //
  1777. // While the Wwait command is waiting it processes events in the normal
  1778. // fashion, so the application will continue to respond to user interactions.
  1779. // If an event handler invokes Wait again, the nested call to Wait must
  1780. // complete before the outer call can complete.
  1781. func (w *Window) WaitVisibility() {
  1782. evalErr(fmt.Sprintf("tkwait visibility %s", w))
  1783. }
  1784. // IconPhoto — change window icon
  1785. //
  1786. // # Description
  1787. //
  1788. // IconPhoto sets the titlebar icon for window based on the named photo images.
  1789. // If -default is specified, this is applied to all future created toplevels as
  1790. // well. The data in the images is taken as a snapshot at the time of
  1791. // invocation. If the images are later changed, this is not reflected to the
  1792. // titlebar icons. Multiple images are accepted to allow different images sizes
  1793. // (e.g., 16x16 and 32x32) to be provided. The window manager may scale
  1794. // provided icons to an appropriate size.
  1795. //
  1796. // On Windows, the images are packed into a Windows icon structure. This will
  1797. // override an ico specified to wm iconbitmap, and vice versa. This command
  1798. // sets the taskbar icon for the window.
  1799. //
  1800. // On X, the images are arranged into the _NET_WM_ICON X property, which most
  1801. // modern window managers support. A wm iconbitmap may exist simultaneously. It is
  1802. // recommended to use not more than 2 icons, placing the larger icon first. This
  1803. // command also sets the panel icon for the application if the window manager or
  1804. // desktop environment supports it.
  1805. //
  1806. // On Macintosh, the first image called is loaded into an OSX-native icon
  1807. // format, and becomes the application icon in dialogs, the Dock, and other
  1808. // contexts. At the script level the command will accept only the first image
  1809. // passed in the parameters as support for multiple sizes/resolutions on macOS
  1810. // is outside Tk's scope. Developers should use the largest icon they can
  1811. // support (preferably 512 pixels) to ensure smooth rendering on the Mac.
  1812. //
  1813. // More information might be available at the [Tcl/Tk wm] page.
  1814. //
  1815. // [Tcl/Tk wm]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/wm.html
  1816. func (w *Window) IconPhoto(options ...Opt) {
  1817. evalErr(fmt.Sprintf("wm iconphoto %s %s", w, collect(options...)))
  1818. if w == App {
  1819. appIconPhotoDone = true
  1820. }
  1821. }
  1822. // DefaultIcon option.
  1823. //
  1824. // Known uses:
  1825. // - [IconPhoto] (command specific)
  1826. func DefaultIcon(val ...any) Opt {
  1827. return rawOption("-default")
  1828. }
  1829. // WmTitle — change the window manager title
  1830. //
  1831. // # Description
  1832. //
  1833. // If string is specified, then it will be passed to the window manager for use
  1834. // as the title for window (the window manager should display this string in
  1835. // window's title bar). In this case the command returns an empty string. If
  1836. // string is not specified then the command returns the current title for the
  1837. // window. The title for a window defaults to its name.
  1838. //
  1839. // More information might be available at the [Tcl/Tk wm] page.
  1840. //
  1841. // [Tcl/Tk wm]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/wm.html
  1842. func (w *Window) WmTitle(s string) string {
  1843. if s != "" {
  1844. s = tclSafeString(s)
  1845. }
  1846. return evalErr(fmt.Sprintf("wm title %s %s", w, s))
  1847. }
  1848. // Center centers 'w' and returns 'w'.
  1849. func (w *Window) Center() *Window {
  1850. if w == App {
  1851. autocenterDisabled = true
  1852. }
  1853. evalErr(fmt.Sprintf("tk::PlaceWindow %s center", w))
  1854. return w
  1855. }
  1856. // Grid — Geometry manager that arranges widgets in a grid
  1857. //
  1858. // # Description
  1859. //
  1860. // If no options are supplied, a list of all of the content in window is
  1861. // returned, most recently managed first. Option can be either -row or -column
  1862. // which causes only the content in the row (or column) specified by value to
  1863. // be returned.
  1864. //
  1865. // More information might be available at the [Tcl/Tk grid] page.
  1866. //
  1867. // [Tcl/Tk grid]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/grid.html
  1868. func GridContent(w *Window, opts ...Opt) (r []*Window) {
  1869. var s string
  1870. if len(opts) != 0 {
  1871. s = collect(opts...)
  1872. }
  1873. for _, v := range parseList(evalErr(fmt.Sprintf("grid content %s %s", w, s))) {
  1874. if w := windowIndex[v]; w != nil {
  1875. r = append(r, w)
  1876. }
  1877. }
  1878. return r
  1879. }
  1880. // Grid — Geometry manager that arranges widgets in a grid
  1881. //
  1882. // # Description
  1883. //
  1884. // Synonym for [GridContent].
  1885. //
  1886. // More information might be available at the [Tcl/Tk grid] page.
  1887. //
  1888. // [Tcl/Tk grid]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/grid.html
  1889. func GridSlaves(w *Window, opts ...Opt) (r []*Window) {
  1890. return GridContent(w, opts...)
  1891. }
  1892. // Grid — Geometry manager that arranges widgets in a grid
  1893. //
  1894. // # Description
  1895. //
  1896. // Removes each of the windows from grid for its container and unmaps their
  1897. // windows. The content will no longer be managed by the grid geometry manager.
  1898. // The configuration options for that window are forgotten, so that if the
  1899. // window is managed once more by the grid geometry manager, the initial
  1900. // default settings are used.
  1901. //
  1902. // If the last content window of the container becomes unmanaged, this will
  1903. // also send the virtual event <<NoManagedChild>> to the container; the
  1904. // container may choose to resize itself (or otherwise respond) to such a
  1905. // change.
  1906. //
  1907. // More information might be available at the [Tcl/Tk grid] page.
  1908. //
  1909. // [Tcl/Tk grid]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/grid.html
  1910. func GridForget(w ...*Window) {
  1911. if len(w) == 0 {
  1912. return
  1913. }
  1914. var a []string
  1915. for _, v := range w {
  1916. if v != nil {
  1917. a = append(a, v.String())
  1918. }
  1919. }
  1920. evalErr(fmt.Sprintf("grid forget %s", strings.Join(a, " ")))
  1921. }
  1922. // Grid — Geometry manager that arranges widgets in a grid
  1923. //
  1924. // # Description
  1925. //
  1926. // Removes each of the windows from grid for its container and unmaps their
  1927. // windows. The content will no longer be managed by the grid geometry manager.
  1928. // However, the configuration options for that window are remembered, so that
  1929. // if the content window is managed once more by the grid geometry manager, the
  1930. // previous values are retained.
  1931. //
  1932. // If the last content window of the container becomes unmanaged, this will
  1933. // also send the virtual event <<NoManagedChild>> to the container; the
  1934. // container may choose to resize itself (or otherwise respond) to such a
  1935. // change.
  1936. //
  1937. // More information might be available at the [Tcl/Tk grid] page.
  1938. //
  1939. // [Tcl/Tk grid]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/grid.html
  1940. func GridRemove(w ...*Window) {
  1941. if len(w) == 0 {
  1942. return
  1943. }
  1944. var a []string
  1945. for _, v := range w {
  1946. if v != nil {
  1947. a = append(a, v.String())
  1948. }
  1949. }
  1950. evalErr(fmt.Sprintf("grid remove %s", strings.Join(a, " ")))
  1951. }
  1952. // Grid — Geometry manager that arranges widgets in a grid
  1953. //
  1954. // # Description
  1955. //
  1956. // The arguments consist of the names of one or more content windows followed
  1957. // by pairs of arguments that specify how to manage the content. The characters
  1958. // -, x and ^, can be specified instead of a window name to alter the default
  1959. // location of a window, as described in the RELATIVE PLACEMENT section, below.
  1960. //
  1961. // The following options are supported:
  1962. //
  1963. // - [Column] n
  1964. //
  1965. // Insert the window so that it occupies the nth column in the grid. Column
  1966. // numbers start with 0. If this option is not supplied, then the window is
  1967. // arranged just to the right of previous window specified on this call to
  1968. // grid, or column “0” if it is the first window. For each x that immediately
  1969. // precedes the window, the column position is incremented by one. Thus the x
  1970. // represents a blank column for this row in the grid.
  1971. //
  1972. // - [Columnspan] n
  1973. //
  1974. // Insert the window so that it occupies n columns in the grid. The default is
  1975. // one column, unless the window name is followed by a -, in which case the
  1976. // columnspan is incremented once for each immediately following -.
  1977. //
  1978. // - [In] container
  1979. //
  1980. // Insert the window(s) in the container window given by container. The default
  1981. // is the first window's parent window.
  1982. //
  1983. // - [Ipadx] amount
  1984. //
  1985. // The amount specifies how much horizontal internal padding to leave on each
  1986. // side of the content. This is space is added inside the content border. The
  1987. // amount must be a valid screen distance, such as 2 or .5c. It defaults to 0.
  1988. //
  1989. // - [Ipady] amount
  1990. //
  1991. // The amount specifies how much vertical internal padding to leave on the top
  1992. // and bottom of the content. This space is added inside the content border.
  1993. // The amount defaults to 0.
  1994. //
  1995. // - [Padx] amount
  1996. //
  1997. // The amount specifies how much horizontal external padding to leave on each
  1998. // side of the content, in screen units. Amount may be a list of two values to
  1999. // specify padding for left and right separately. The amount defaults to 0.
  2000. // This space is added outside the content border.
  2001. //
  2002. // - [Pady] amount
  2003. //
  2004. // The amount specifies how much vertical external padding to leave on the top
  2005. // and bottom of the content, in screen units. Amount may be a list of two
  2006. // values to specify padding for top and bottom separately. The amount defaults
  2007. // to 0. This space is added outside the content border.
  2008. //
  2009. // - [Row] n
  2010. //
  2011. // Insert the content so that it occupies the nth row in the grid. Row numbers
  2012. // start with 0. If this option is not supplied, then the content is arranged
  2013. // on the same row as the previous content specified on this call to grid, or
  2014. // the next row after the highest occupied row if this is the first content.
  2015. //
  2016. // - [Rowspan] n
  2017. //
  2018. // Insert the content so that it occupies n rows in the grid. The default is
  2019. // one row. If the next grid command contains ^ characters instead of content
  2020. // that line up with the columns of this content, then the rowspan of this
  2021. // content is extended by one.
  2022. //
  2023. // - [Sticky] style
  2024. //
  2025. // If a content's cell is larger than its requested dimensions, this option may
  2026. // be used to position (or stretch) the content within its cell. Style is a
  2027. // string that contains zero or more of the characters n, s, e or w. The string
  2028. // can optionally contain spaces or commas, but they are ignored. Each letter
  2029. // refers to a side (north, south, east, or west) that the content will “stick”
  2030. // to. If both n and s (or e and w) are specified, the content will be
  2031. // stretched to fill the entire height (or width) of its cavity. The -sticky
  2032. // option subsumes the combination of -anchor and -fill that is used by pack.
  2033. // The default is “”, which causes the content to be centered in its cavity, at
  2034. // its requested size.
  2035. //
  2036. // If any of the content is already managed by the geometry manager then any
  2037. // unspecified options for them retain their previous values rather than
  2038. // receiving default values.
  2039. //
  2040. // More information might be available at the [Tcl/Tk grid] page.
  2041. //
  2042. // [Tcl/Tk grid]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/grid.html
  2043. func Grid(w Widget, options ...Opt) {
  2044. evalErr(fmt.Sprintf("grid configure %s %s", w, collect(options...)))
  2045. }
  2046. // Grid — Geometry manager that arranges widgets in a grid
  2047. //
  2048. // # Description
  2049. //
  2050. // The anchor value controls how to place the grid within the container window
  2051. // when no row/column has any weight. See THE GRID ALGORITHM below for further
  2052. // details. The default anchor is nw.
  2053. //
  2054. // More information might be available at the [Tcl/Tk grid] page.
  2055. //
  2056. // [Tcl/Tk grid]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/grid.html
  2057. func GridAnchor(w *Window, anchor string) string {
  2058. return evalErr(fmt.Sprintf("grid anchor %s %s", w, tclSafeString(anchor)))
  2059. }
  2060. // Grid — Geometry manager that arranges widgets in a grid
  2061. //
  2062. // # Description
  2063. //
  2064. // Query or set the row properties of the index row of the geometry container,
  2065. // window. The valid options are -minsize, -weight, -uniform and -pad. If one
  2066. // or more options are provided, then index may be given as a list of row
  2067. // indices to which the configuration options will operate on. Indices may be
  2068. // integers, window names or the keyword all. For all the options apply to all
  2069. // rows currently occupied by content windows. For a window name, that window
  2070. // must be a content window of this container and the options apply to all rows
  2071. // currently occupied by the container window. The -minsize option sets the
  2072. // minimum size, in screen units, that will be permitted for this row. The
  2073. // -weight option (an integer value) sets the relative weight for apportioning
  2074. // any extra spaces among rows. A weight of zero (0) indicates the row will not
  2075. // deviate from its requested size. A row whose weight is two will grow at
  2076. // twice the rate as a row of weight one when extra space is allocated to the
  2077. // layout. The -uniform option, when a non-empty value is supplied, places the
  2078. // row in a uniform group with other rows that have the same value for
  2079. // -uniform. The space for rows belonging to a uniform group is allocated so
  2080. // that their sizes are always in strict proportion to their -weight values.
  2081. // See THE GRID ALGORITHM below for further details. The -pad option specifies
  2082. // the number of screen units that will be added to the largest window
  2083. // contained completely in that row when the grid geometry manager requests a
  2084. // size from the containing window. If only an option is specified, with no
  2085. // value, the current value of that option is returned. If only the container
  2086. // window and index is specified, all the current settings are returned in a
  2087. // list of “-option value” pairs.
  2088. //
  2089. // More information might be available at the [Tcl/Tk grid] page.
  2090. //
  2091. // [Tcl/Tk grid]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/grid.html
  2092. func GridRowConfigure(w Widget, index any, options ...Opt) {
  2093. switch x := index.(type) {
  2094. case []int:
  2095. s := fmt.Sprint(x)
  2096. index = "{" + s[1:len(s)-1] + "}"
  2097. default:
  2098. index = tclSafeString(fmt.Sprint(index))
  2099. }
  2100. evalErr(fmt.Sprintf("grid rowconfigure %s %v %s", w, index, collect(options...)))
  2101. }
  2102. // Minsize option.
  2103. //
  2104. // Known uses:
  2105. // - [GridColumnConfigure]
  2106. // - [GridRowConfigure]
  2107. func Minsize(val ...any) Opt {
  2108. return rawOption(fmt.Sprintf(`-minsize %s`, collectAny(val...)))
  2109. }
  2110. // Grid — Geometry manager that arranges widgets in a grid
  2111. //
  2112. // # Description
  2113. //
  2114. // Query or set the column properties of the index column of the geometry
  2115. // container, window. The valid options are -minsize, -weight, -uniform and
  2116. // -pad. If one or more options are provided, then index may be given as a list
  2117. // of column indices to which the configuration options will operate on.
  2118. // Indices may be integers, window names or the keyword all. For all the
  2119. // options apply to all columns currently occupied be content windows. For a
  2120. // window name, that window must be a content of this container and the options
  2121. // apply to all columns currently occupied be the content. The -minsize option
  2122. // sets the minimum size, in screen units, that will be permitted for this
  2123. // column. The -weight option (an integer value) sets the relative weight for
  2124. // apportioning any extra spaces among columns. A weight of zero (0) indicates
  2125. // the column will not deviate from its requested size. A column whose weight
  2126. // is two will grow at twice the rate as a column of weight one when extra
  2127. // space is allocated to the layout. The -uniform option, when a non-empty
  2128. // value is supplied, places the column in a uniform group with other columns
  2129. // that have the same value for -uniform. The space for columns belonging to a
  2130. // uniform group is allocated so that their sizes are always in strict
  2131. // proportion to their -weight values. See THE GRID ALGORITHM below for further
  2132. // details. The -pad option specifies the number of screen units that will be
  2133. // added to the largest window contained completely in that column when the
  2134. // grid geometry manager requests a size from the containing window. If only an
  2135. // option is specified, with no value, the current value of that option is
  2136. // returned. If only the container window and index is specified, all the
  2137. // current settings are returned in a list of “-option value” pairs.
  2138. //
  2139. // More information might be available at the [Tcl/Tk grid] page.
  2140. //
  2141. // [Tcl/Tk grid]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/grid.html
  2142. func GridColumnConfigure(w Widget, index any, options ...Opt) {
  2143. switch x := index.(type) {
  2144. case []int:
  2145. s := fmt.Sprint(x)
  2146. index = "{" + s[1:len(s)-1] + "}"
  2147. default:
  2148. index = tclSafeString(fmt.Sprint(index))
  2149. }
  2150. evalErr(fmt.Sprintf("grid columnconfigure %s %v %s", w, index, collect(options...)))
  2151. }
  2152. // Pad option.
  2153. //
  2154. // The -pad option specifies the number of screen units that will be added to
  2155. // the largest window contained completely in that column/row when the grid
  2156. // geometry manager requests a size from the containing window.
  2157. //
  2158. // Known uses:
  2159. // - [GridColumnConfigure] (command specific)
  2160. // - [GridRowConfigure] (command specific)
  2161. func Pad(val any) Opt {
  2162. return rawOption(fmt.Sprintf(`-pad %s`, tclSafeString(fmt.Sprint(val))))
  2163. }
  2164. // Configure alters the configuration of 'w' and returns 'w'.
  2165. func (w *Window) Configure(options ...Opt) *Window {
  2166. options, tvs, vs := w.split(options)
  2167. if len(options) != 0 {
  2168. evalErr(fmt.Sprintf("%s configure %s", w, collect(options...)))
  2169. }
  2170. if len(tvs) != 0 {
  2171. tvo := tvs[len(tvs)-1]
  2172. tclVar := textVariables[w]
  2173. if tclVar == "" {
  2174. tclVar = fmt.Sprintf("textVar%d", id.Add(1))
  2175. textVariables[w] = tclVar
  2176. evalErr(fmt.Sprintf("%s configure -textvariable %s", w, tclVar))
  2177. }
  2178. evalErr(fmt.Sprintf("set %s %s", tclVar, tclSafeString(string(tvo))))
  2179. }
  2180. if len(vs) != 0 {
  2181. vo := vs[len(vs)-1]
  2182. variables[w] = vo
  2183. if vo.tclName == "" {
  2184. vo.tclName = fmt.Sprintf("goVar%d", id.Add(1))
  2185. }
  2186. evalErr(fmt.Sprintf("%s configure -variable %s", w, vo.tclName))
  2187. evalErr(fmt.Sprintf("set %s %s", vo.tclName, tclSafeString(fmt.Sprint(vo.val))))
  2188. }
  2189. return w
  2190. }
  2191. // ttk::widget — Standard options and commands supported by Tk themed widgets
  2192. //
  2193. // # Description
  2194. //
  2195. // Modify or inquire widget state. If stateSpec is not "", sets the widget
  2196. // state: for each flag in stateSpec, sets the corresponding flag or clears it
  2197. // if prefixed by an exclamation point. Returns a new state spec indicating
  2198. // which flags were changed.
  2199. //
  2200. // If stateSpec is "", returns a list of the currently-enabled state flags.
  2201. //
  2202. // # Widget States
  2203. //
  2204. // The widget state is a bitmap of independent state flags. Widget state flags include:
  2205. //
  2206. // - active:
  2207. // The mouse cursor is over the widget and pressing a mouse button will
  2208. // cause some action to occur. (aka “prelight” (Gnome), “hot” (Windows),
  2209. // “hover”).
  2210. // - disabled:
  2211. // Widget is disabled under program control (aka “unavailable”,
  2212. // “inactive”).
  2213. // - focus:
  2214. // Widget has keyboard focus.
  2215. // - pressed:
  2216. // Widget is being pressed (aka “armed” in Motif).
  2217. // - selected:
  2218. // “On”, “true”, or “current” for things like checkbuttons and
  2219. // radiobuttons.
  2220. // - background:
  2221. // Windows and the Mac have a notion of an “active” or foreground window.
  2222. // The background state is set for widgets in a background window, and
  2223. // cleared for those in the foreground window.
  2224. // - readonly:
  2225. // Widget should not allow user modification.
  2226. // - alternate:
  2227. // A widget-specific alternate display format. For example, used for
  2228. // checkbuttons and radiobuttons in the “tristate” or “mixed” state, and
  2229. // for buttons with -default active.
  2230. // - invalid:
  2231. // The widget's value is invalid. (Potential uses: scale widget value out
  2232. // of bounds, entry widget value failed validation.)
  2233. // - hover:
  2234. // The mouse cursor is within the widget. This is similar to the active
  2235. // state; it is used in some themes for widgets that provide distinct
  2236. // visual feedback for the active widget in addition to the active element
  2237. // within the widget.
  2238. // - user1-user6
  2239. // Freely usable for other purposes
  2240. //
  2241. // A state specification or stateSpec is a list of state names, optionally
  2242. // prefixed with an exclamation point (!) indicating that the bit is off.
  2243. func (w *Window) WidgetState(stateSpec string) (r string) {
  2244. if stateSpec != "" {
  2245. stateSpec = tclSafeString(stateSpec)
  2246. }
  2247. return evalErr(fmt.Sprintf("%s state %s", w, stateSpec))
  2248. }
  2249. // tk_messageBox — pops up a message window and waits for user response.
  2250. //
  2251. // # Description
  2252. //
  2253. // This procedure creates and displays a message window with an
  2254. // application-specified message, an icon and a set of buttons. Each of the
  2255. // buttons in the message window is identified by a unique symbolic name (see
  2256. // the -type options). After the message window is popped up, tk_messageBox
  2257. // waits for the user to select one of the buttons. Then it returns the
  2258. // symbolic name of the selected button. The following optins are
  2259. // supported:
  2260. //
  2261. // - [Command] handler
  2262. //
  2263. // Specifies the handler to invoke when the user closes the
  2264. // dialog. The actual command consists of string followed by a space and the
  2265. // name of the button clicked by the user to close the dialog. This is only
  2266. // available on Mac OS X.
  2267. //
  2268. // - [Default] name
  2269. //
  2270. // Name gives the symbolic name of the default button for this message window (
  2271. // “ok”, “cancel”, and so on). See -type for a list of the symbolic names. If
  2272. // this option is not specified, the first button in the dialog will be made
  2273. // the default.
  2274. //
  2275. // - [Detail] string
  2276. //
  2277. // Specifies an auxiliary message to the main message given by the -message
  2278. // option. The message detail will be presented beneath the main message and,
  2279. // where supported by the OS, in a less emphasized font than the main message.
  2280. //
  2281. // - [Icon] iconImage
  2282. //
  2283. // Specifies an icon to display. IconImage must be one of the following: error,
  2284. // info, question or warning. If this option is not specified, then the info
  2285. // icon will be displayed.
  2286. //
  2287. // - [Message] string
  2288. //
  2289. // Specifies the message to display in this message box. The default value is
  2290. // an empty string.
  2291. //
  2292. // - [Parent] window
  2293. //
  2294. // Makes window the logical parent of the message box. The message box is
  2295. // displayed on top of its parent window.
  2296. //
  2297. // - [Title] titleString
  2298. //
  2299. // Specifies a string to display as the title of the message box. The default
  2300. // value is an empty string.
  2301. //
  2302. // - [Type] predefinedType
  2303. //
  2304. // Arranges for a predefined set of buttons to be displayed. The following
  2305. // values are possible for predefinedType:
  2306. //
  2307. // - abortretryignore - Displays three buttons whose symbolic names are abort, retry and ignore.
  2308. // - ok - Displays one button whose symbolic name is ok.
  2309. // - okcancel - Displays two buttons whose symbolic names are ok and cancel.
  2310. // - retrycancel - Displays two buttons whose symbolic names are retry and cancel.
  2311. // - yesno - Displays two buttons whose symbolic names are yes and no.
  2312. // - yesnocancel - Displays three buttons whose symbolic names are yes, no and cancel.
  2313. //
  2314. // More information might be available at the [Tcl/Tk messageBox] page.
  2315. //
  2316. // [Tcl/Tk messageBox]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/messageBox.html
  2317. func MessageBox(options ...Opt) string {
  2318. return evalErr(fmt.Sprintf("tk_messageBox %s", collect(options...)))
  2319. }
  2320. // Bell — Ring a display's bell
  2321. //
  2322. // # Description
  2323. //
  2324. // This command rings the bell on the display for window and returns an empty
  2325. // string. If the -displayof option is omitted, the display of the
  2326. // application's main window is used by default. The command uses the current
  2327. // bell-related settings for the display, which may be modified with programs
  2328. // such as xset.
  2329. //
  2330. // If -nice is not specified, this command also resets the screen saver for the
  2331. // screen. Some screen savers will ignore this, but others will reset so that
  2332. // the screen becomes visible again.
  2333. //
  2334. // - [Displayof] window
  2335. // - [Nice]
  2336. //
  2337. // More information might be available at the [Tcl/Tk bell] page.
  2338. //
  2339. // [Tcl/Tk bell]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/bell.html
  2340. func Bell(options ...Opt) {
  2341. evalErr(fmt.Sprintf("bell %s", collect(options...)))
  2342. }
  2343. // ChooseColor — pops up a dialog box for the user to select a color.
  2344. //
  2345. // # Description
  2346. //
  2347. // ChooseColor pops up a dialog box for the user to select a color. The
  2348. // following option-value pairs are possible as command line arguments:
  2349. //
  2350. // - [Initialcolor] color
  2351. //
  2352. // Specifies the color to display in the color dialog when it pops up. color
  2353. // must be in a form acceptable to the Tk_GetColor function.
  2354. //
  2355. // - [Parent] window
  2356. //
  2357. // Makes window the logical parent of the color dialog. The color dialog is
  2358. // displayed on top of its parent window.
  2359. //
  2360. // - [Title] titleString
  2361. //
  2362. // Specifies a string to display as the title of the dialog box. If this option
  2363. // is not specified, then a default title will be displayed.
  2364. //
  2365. // If the user selects a color, ChooseColor will return the name of the
  2366. // color in a form acceptable to Tk_GetColor. If the user cancels the
  2367. // operation, both commands will return the empty string.
  2368. //
  2369. // More information might be available at the [Tcl/Tk choosecolor] page.
  2370. //
  2371. // [Tcl/Tk choosecolor]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/chooseColor.html
  2372. func ChooseColor(options ...Opt) string {
  2373. return evalErr(fmt.Sprintf("tk_chooseColor %s", collect(options...)))
  2374. }
  2375. // Busy — confine pointer events to a window sub-tree
  2376. //
  2377. // # Description
  2378. //
  2379. // The Busy command provides a simple means to block pointer events from Tk
  2380. // widgets, while overriding the widget's cursor with a configurable busy
  2381. // cursor. Note this command does not prevent keyboard events from being sent
  2382. // to the widgets made busy.
  2383. //
  2384. // - [Cursor] cursorName
  2385. //
  2386. // Specifies the cursor to be displayed when the widget is made busy.
  2387. // CursorName can be in any form accepted by Tk_GetCursor. The default cursor
  2388. // is wait on Windows and watch on other platforms.
  2389. //
  2390. // More information might be available at the [Tcl/Tk busy] page.
  2391. //
  2392. // [Tcl/Tk update]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/busy.html
  2393. func (w *Window) Busy(options ...Opt) {
  2394. evalErr(fmt.Sprintf("tk busy %s %s", w, collect(options...)))
  2395. }
  2396. // BusyForget — undo Busy
  2397. //
  2398. // # Description
  2399. //
  2400. // Releases resources allocated by the [Window.Busy] command for window, including
  2401. // the transparent window. User events will again be received by window.
  2402. // Resources are also released when window is destroyed. Window must be the
  2403. // name of a widget specified in the hold operation, otherwise an error is
  2404. // reported.
  2405. //
  2406. // More information might be available at the [Tcl/Tk busy] page.
  2407. //
  2408. // [Tcl/Tk update]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/busy.html
  2409. func (w *Window) BusyForget(options ...Opt) {
  2410. evalErr(fmt.Sprintf("tk busy forget %s %s", w, collect(options...)))
  2411. }
  2412. // Update — Process pending events and idle callbacks
  2413. //
  2414. // More information might be available at the [Tcl/Tk update] page.
  2415. //
  2416. // [Tcl/Tk update]: https://www.tcl-lang.org/man/tcl9.0/TclCmd/update.html
  2417. func Update() {
  2418. evalErr("update")
  2419. }
  2420. //TODO?
  2421. // - [Command] string
  2422. //
  2423. // Specifies the prefix of a Tcl command to invoke when the user closes the
  2424. // dialog after having selected an item. This callback is not called if the
  2425. // user cancelled the dialog. The actual command consists of string followed by
  2426. // a space and the value selected by the user in the dialog. This is only
  2427. // available on Mac OS X.
  2428. // ChooseDirectory — pops up a dialog box for the user to select a directory.
  2429. //
  2430. // # Description
  2431. //
  2432. // The procedure tk_chooseDirectory pops up a dialog box for the user to select
  2433. // a directory. The following option-value pairs are possible as command line
  2434. // arguments:
  2435. //
  2436. // - [Initialdir] dirname
  2437. //
  2438. // Specifies that the directories in directory should be displayed when the
  2439. // dialog pops up. If this parameter is not specified, the initial directory
  2440. // defaults to the current working directory on non-Windows systems and on
  2441. // Windows systems prior to Vista. On Vista and later systems, the initial
  2442. // directory defaults to the last user-selected directory for the application.
  2443. // If the parameter specifies a relative path, the return value will convert
  2444. // the relative path to an absolute path.
  2445. //
  2446. // - [Message] string
  2447. //
  2448. // Specifies a message to include in the client area of the dialog. This is
  2449. // only available on Mac OS X.
  2450. //
  2451. // - [Mustexist] boolean
  2452. //
  2453. // Specifies whether the user may specify non-existent directories. If this
  2454. // parameter is true, then the user may only select directories that already
  2455. // exist. The default value is false.
  2456. //
  2457. // - [Parent] window
  2458. //
  2459. // Makes window the logical parent of the dialog. The dialog is displayed on
  2460. // top of its parent window. On Mac OS X, this turns the file dialog into a
  2461. // sheet attached to the parent window.
  2462. //
  2463. // - [Title] titleString
  2464. //
  2465. // Specifies a string to display as the title of the dialog box. If this option
  2466. // is not specified, then a default title will be displayed.
  2467. //
  2468. // More information might be available at the [Tcl/Tk chooseDirectory] page.
  2469. //
  2470. // [Tcl/Tk chooseDirectory]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/chooseDirectory.html
  2471. func ChooseDirectory(options ...Opt) string {
  2472. return evalErr(fmt.Sprintf("tk_chooseDirectory %s", collect(options...)))
  2473. }
  2474. // ClipboardAppend — Manipulate Tk clipboard
  2475. //
  2476. // # Description
  2477. //
  2478. // This command provides a Tcl interface to the Tk clipboard, which stores data
  2479. // for later retrieval using the selection mechanism (via the -selection
  2480. // CLIPBOARD option). In order to copy data into the clipboard, clipboard clear
  2481. // must be called, followed by a sequence of one or more calls to clipboard
  2482. // append. To ensure that the clipboard is updated atomically, all appends
  2483. // should be completed before returning to the event loop.
  2484. //
  2485. // ClipboardAppend appends 'data' to the clipboard on window's display in the
  2486. // form given by type with the representation given by format and claims
  2487. // ownership of the clipboard on window's display.
  2488. //
  2489. // - [Displayof] window
  2490. //
  2491. // - [Format] format
  2492. //
  2493. // The format argument specifies the representation that should be used to
  2494. // transmit the selection to the requester (the second column of Table 2 of the
  2495. // ICCCM), and defaults to STRING. If format is STRING, the selection is
  2496. // transmitted as 8-bit ASCII characters. If format is ATOM, then the data is
  2497. // divided into fields separated by white space; each field is converted to its
  2498. // atom value, and the 32-bit atom value is transmitted instead of the atom
  2499. // name. For any other format, data is divided into fields separated by white
  2500. // space and each field is converted to a 32-bit integer; an array of integers
  2501. // is transmitted to the selection requester. Note that strings passed to
  2502. // clipboard append are concatenated before conversion, so the caller must take
  2503. // care to ensure appropriate spacing across string boundaries. All items
  2504. // appended to the clipboard with the same type must have the same format.
  2505. //
  2506. // The format argument is needed only for compatibility with clipboard
  2507. // requesters that do not use Tk. If the Tk toolkit is being used to retrieve
  2508. // the CLIPBOARD selection then the value is converted back to a string at the
  2509. // requesting end, so format is irrelevant.
  2510. //
  2511. // - [Type] type
  2512. //
  2513. // Type specifies the form in which the selection is to be returned (the
  2514. // desired “target” for conversion, in ICCCM terminology), and should be an
  2515. // atom name such as STRING or FILE_NAME; see the Inter-Client Communication
  2516. // Conventions Manual for complete details. Type defaults to STRING.
  2517. //
  2518. // More information might be available at the [Tcl/Tk clipboard] page.
  2519. //
  2520. // [Tcl/Tk clipboard]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/clipboard.html
  2521. func ClipboardAppend(data string, options ...Opt) {
  2522. evalErr(fmt.Sprintf("clipboard append %s -- %s", collect(options...), tclSafeString(data)))
  2523. }
  2524. // ClipboardClear — Manipulate Tk clipboard
  2525. //
  2526. // # Description
  2527. //
  2528. // Claims ownership of the clipboard on window's display and removes any
  2529. // previous contents. Window defaults to App. Returns an empty string.
  2530. //
  2531. // More information might be available at the [Tcl/Tk clipboard] page.
  2532. //
  2533. // [Tcl/Tk clipboard]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/clipboard.html
  2534. func ClipboardClear(options ...Opt) {
  2535. evalErr(fmt.Sprintf("clipboard clear %s", collect(options...)))
  2536. }
  2537. // ClipboardGet — Manipulate Tk clipboard
  2538. //
  2539. // # Description
  2540. //
  2541. // Retrieve data from the clipboard on window's display. Window defaults to App.
  2542. //
  2543. // - [Displayof] window
  2544. //
  2545. // - [Type] type
  2546. //
  2547. // Type specifies the form in which the data is to be returned and should be an
  2548. // atom name such as STRING or FILE_NAME. Type defaults to STRING. This command
  2549. // is equivalent to [SelectionGet](Selection("CLIPBOARD").
  2550. //
  2551. // Note that on modern X11 systems, the most useful type to retrieve for
  2552. // transferred strings is not STRING, but rather UTF8_STRING.
  2553. //
  2554. // More information might be available at the [Tcl/Tk clipboard] page.
  2555. //
  2556. // [Tcl/Tk clipboard]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/clipboard.html
  2557. func ClipboardGet(options ...Opt) string {
  2558. return evalErr(fmt.Sprintf("clipboard get %s", collect(options...)))
  2559. }
  2560. var onceForceInit bool
  2561. func forceInit() {
  2562. if onceForceInit {
  2563. return
  2564. }
  2565. defer func() { onceForceInit = true }()
  2566. evalErr("# forceInit() executed")
  2567. }
  2568. // ExitHandler returns a canned [Command] that destroys the [App].
  2569. func ExitHandler() Opt {
  2570. forceInit()
  2571. return exitHandler
  2572. }
  2573. // Exit provides a canned [Button] with default [Txt] "Exit", bound to the
  2574. // [ExitHandler].
  2575. //
  2576. // Use [Window.Exit] to create a Exit with a particular parent.
  2577. func Exit(options ...Opt) *ButtonWidget {
  2578. return App.Exit(options...)
  2579. }
  2580. // Exit provides a canned [Button] with default [Txt] "Exit", bound to the
  2581. // [ExitHandler].
  2582. //
  2583. // The resulting [Window] is a child of 'w'
  2584. func (w *Window) Exit(options ...Opt) *ButtonWidget {
  2585. switch {
  2586. case isVNC:
  2587. return Tooltip(w.Button(append([]Opt{Txt("Disconnect"), ExitHandler()}, options...)...), disconnectButtonTooltip).(*ButtonWidget)
  2588. default:
  2589. return Tooltip(w.Button(append([]Opt{Txt("Exit"), ExitHandler()}, options...)...), exitButtonTooltip).(*ButtonWidget)
  2590. }
  2591. }
  2592. // TExit provides a canned [TButton] with default [Txt] "Exit", bound to the
  2593. // [ExitHandler].
  2594. //
  2595. // Use [Window.TExit] to create a TExit with a particular parent.
  2596. func TExit(options ...Opt) *TButtonWidget {
  2597. return App.TExit(options...)
  2598. }
  2599. // TExit provides a canned [TButton] with default [Txt] "Exit", bound to the
  2600. // [ExitHandler].
  2601. //
  2602. // The resulting [Window] is a child of 'w'
  2603. func (w *Window) TExit(options ...Opt) *TButtonWidget {
  2604. switch {
  2605. case isVNC:
  2606. return Tooltip(w.TButton(append([]Opt{Txt("Disconnect"), ExitHandler()}, options...)...), disconnectButtonTooltip).(*TButtonWidget)
  2607. default:
  2608. return Tooltip(w.TButton(append([]Opt{Txt("Exit"), ExitHandler()}, options...)...), exitButtonTooltip).(*TButtonWidget)
  2609. }
  2610. }
  2611. var _ Opt = (*VariableOpt)(nil)
  2612. // VariableOpt is an Opt linking Go and Tcl variables.
  2613. type VariableOpt struct {
  2614. tclName string
  2615. val any
  2616. }
  2617. // Set sets the value of the linked Tcl variable.
  2618. func (v *VariableOpt) Set(val any) {
  2619. if v == nil || v.tclName == "" {
  2620. fail(fmt.Errorf("%T not linked", v))
  2621. return
  2622. }
  2623. evalErr(fmt.Sprintf("set %s %s", v.tclName, tclSafeString(fmt.Sprint(val))))
  2624. }
  2625. // Get return the value of the linked Tcl variable.
  2626. func (v *VariableOpt) Get() (r string) {
  2627. if v == nil || v.tclName == "" {
  2628. fail(fmt.Errorf("%T not linked", v))
  2629. return
  2630. }
  2631. return evalErr(fmt.Sprintf("set %s", v.tclName))
  2632. }
  2633. func (*VariableOpt) optionString(*Window) string {
  2634. panic("internal error") // Not supposed to be invoked.
  2635. }
  2636. // Variable option.
  2637. //
  2638. // Known uses:
  2639. // - [Checkbutton] (widget specific)
  2640. // - [MenuWidget.AddCascade] (command specific)
  2641. // - [MenuWidget.AddCommand] (command specific)
  2642. // - [MenuWidget.AddSeparator] (command specific)
  2643. // - [Radiobutton] (widget specific)
  2644. // - [Scale] (widget specific)
  2645. // - [TCheckbutton] (widget specific)
  2646. // - [TProgressbar] (widget specific)
  2647. // - [TRadiobutton] (widget specific)
  2648. // - [TScale] (widget specific)
  2649. func Variable(val any) *VariableOpt {
  2650. return &VariableOpt{val: val}
  2651. }
  2652. // Variable — Get the configured option value.
  2653. //
  2654. // Known uses:
  2655. // - [Checkbutton] (widget specific)
  2656. // - [Radiobutton] (widget specific)
  2657. // - [Scale] (widget specific)
  2658. // - [TCheckbutton] (widget specific)
  2659. // - [TProgressbar] (widget specific)
  2660. // - [TRadiobutton] (widget specific)
  2661. // - [TScale] (widget specific)
  2662. func (w *Window) Variable() string {
  2663. if tclVar := variables[w]; tclVar != nil {
  2664. return evalErr(fmt.Sprintf("set %s", tclVar.tclName))
  2665. }
  2666. return ""
  2667. }
  2668. type textVarOpt string
  2669. func (textVarOpt) optionString(*Window) string {
  2670. panic("internal error") // Not supposed to be invoked.
  2671. }
  2672. // Textvariable option.
  2673. //
  2674. // Specifies the value to be displayed inside the widget.
  2675. // The way in which the string is displayed in the widget depends on the
  2676. // particular widget and may be determined by other options, such as
  2677. // -anchor or -justify.
  2678. //
  2679. // Known uses:
  2680. // - [Button]
  2681. // - [Checkbutton]
  2682. // - [Entry]
  2683. // - [Label]
  2684. // - [Menubutton]
  2685. // - [Message]
  2686. // - [Radiobutton]
  2687. // - [Spinbox]
  2688. // - [TButton]
  2689. // - [TCheckbutton]
  2690. // - [TCombobox] (widget specific)
  2691. // - [TEntry] (widget specific)
  2692. // - [TLabel]
  2693. // - [TMenubutton]
  2694. // - [TRadiobutton]
  2695. func Textvariable(s string) Opt {
  2696. return textVarOpt(s)
  2697. }
  2698. // Textvariable — Get the configured option value.
  2699. //
  2700. // Known uses:
  2701. // - [Button]
  2702. // - [Checkbutton]
  2703. // - [Entry]
  2704. // - [Label]
  2705. // - [Menubutton]
  2706. // - [Message]
  2707. // - [Radiobutton]
  2708. // - [Spinbox]
  2709. // - [TButton]
  2710. // - [TCheckbutton]
  2711. // - [TCombobox] (widget specific)
  2712. // - [TEntry] (widget specific)
  2713. // - [TLabel]
  2714. // - [TMenubutton]
  2715. // - [TRadiobutton]
  2716. func (w *Window) Textvariable() (r string) {
  2717. if tclVar := textVariables[w]; tclVar != "" {
  2718. return evalErr(fmt.Sprintf("set %s", tclVar))
  2719. }
  2720. return ""
  2721. }
  2722. // Focus — Manage the input focus
  2723. //
  2724. // # Description
  2725. //
  2726. // The focus command is used to manage the Tk input focus. At any given time,
  2727. // one window on each display is designated as the focus window; any key press
  2728. // or key release events for the display are sent to that window. It is
  2729. // normally up to the window manager to redirect the focus among the top-level
  2730. // windows of a display. For example, some window managers automatically set
  2731. // the input focus to a top-level window whenever the mouse enters it; others
  2732. // redirect the input focus only when the user clicks on a window. Usually the
  2733. // window manager will set the focus only to top-level windows, leaving it up
  2734. // to the application to redirect the focus among the children of the
  2735. // top-level.
  2736. //
  2737. // Tk remembers one focus window for each top-level (the most recent descendant
  2738. // of that top-level to receive the focus); when the window manager gives the
  2739. // focus to a top-level, Tk automatically redirects it to the remembered
  2740. // window. Within a top-level Tk uses an explicit focus model by default.
  2741. // Moving the mouse within a top-level does not normally change the focus; the
  2742. // focus changes only when a widget decides explicitly to claim the focus
  2743. // (e.g., because of a button click), or when the user types a key such as Tab
  2744. // that moves the focus.
  2745. //
  2746. // The Tcl procedure tk_focusFollowsMouse may be invoked to create an implicit
  2747. // focus model: it reconfigures Tk so that the focus is set to a window
  2748. // whenever the mouse enters it. The Tcl procedures tk_focusNext and
  2749. // tk_focusPrev implement a focus order among the windows of a top-level; they
  2750. // are used in the default bindings for Tab and Shift-Tab, among other things.
  2751. //
  2752. // The focus command can take any of the following forms:
  2753. //
  2754. // Focus()
  2755. //
  2756. // Returns the path name of the focus window on the display containing the
  2757. // application's main window, or an empty string if no window in this
  2758. // application has the focus on that display. Note: it is better to specify the
  2759. // display explicitly using -displayof (see below) so that the code will work
  2760. // in applications using multiple displays.
  2761. //
  2762. // Focus(window)
  2763. //
  2764. // If the application currently has the input focus on window's display, this
  2765. // command resets the input focus for window's display to window and returns an
  2766. // empty string. If the application does not currently have the input focus on
  2767. // window's display, window will be remembered as the focus for its top-level;
  2768. // the next time the focus arrives at the top-level, Tk will redirect it to
  2769. // window. If window is an empty string then the command does nothing.
  2770. //
  2771. // Focus(Displayof(window))
  2772. //
  2773. // Returns the name of the focus window on the display containing window. If
  2774. // the focus window for window's display is not in this application, the return
  2775. // value is an empty string.
  2776. //
  2777. // Focus(Force(window))
  2778. //
  2779. // Sets the focus of window's display to window, even if the application does
  2780. // not currently have the input focus for the display. This command should be
  2781. // used sparingly, if at all. In normal usage, an application should not claim
  2782. // the focus for itself; instead, it should wait for the window manager to give
  2783. // it the focus. If window is an empty string then the command does nothing.
  2784. //
  2785. // Focus(Lastfor(window))
  2786. //
  2787. // Returns the name of the most recent window to have the input focus among all
  2788. // the windows in the same top-level as window. If no window in that top-level
  2789. // has ever had the input focus, or if the most recent focus window has been
  2790. // deleted, then the name of the top-level is returned. The return value is the
  2791. // window that will receive the input focus the next time the window manager
  2792. // gives the focus to the top-level.
  2793. //
  2794. // # Quirks
  2795. //
  2796. // When an internal window receives the input focus, Tk does not actually set
  2797. // the X focus to that window; as far as X is concerned, the focus will stay on
  2798. // the top-level window containing the window with the focus. However, Tk
  2799. // generates FocusIn and FocusOut events just as if the X focus were on the
  2800. // internal window. This approach gets around a number of problems that would
  2801. // occur if the X focus were actually moved; the fact that the X focus is on
  2802. // the top-level is invisible unless you use C code to query the X server
  2803. // directly.
  2804. //
  2805. // More information might be available at the [Tcl/Tk focus] page.
  2806. //
  2807. // [Tcl/Tk focus]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/focus.html
  2808. func Focus(options ...Opt) string {
  2809. return evalErr(fmt.Sprintf("focus %s", collect(options...)))
  2810. }
  2811. // FontFace represents a Tk font.
  2812. type FontFace struct {
  2813. name string
  2814. }
  2815. func (f *FontFace) optionString(_ *Window) (r string) {
  2816. if f != nil {
  2817. return f.name
  2818. }
  2819. return "font0" // does not exist
  2820. }
  2821. // String implements fmt.Stringer.
  2822. func (f *FontFace) String() string {
  2823. return f.optionString(nil)
  2824. }
  2825. // NewFont — Create and inspect fonts.
  2826. //
  2827. // # Description
  2828. //
  2829. // Returns the amount in pixels that the tallest letter sticks up above the baseline
  2830. // of the font, plus any extra blank space added by the designer of the font.
  2831. //
  2832. // Additional information might be available at the [Tcl/Tk font] page.
  2833. //
  2834. // [Tcl/Tk font]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/font.html
  2835. func (f *FontFace) MetricsAscent(window *Window) int {
  2836. metric := evalErr(fmt.Sprintf("font metrics %s -displayof %s -ascent", f.name, window))
  2837. return atoi(metric)
  2838. }
  2839. // NewFont — Create and inspect fonts.
  2840. //
  2841. // # Description
  2842. //
  2843. // Returns the largest amount in pixels that any letter sticks down below the baseline
  2844. // of the font, plus any extra blank space added by the designer of the font.
  2845. //
  2846. // Additional information might be available at the [Tcl/Tk font] page.
  2847. //
  2848. // [Tcl/Tk font]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/font.html
  2849. func (f *FontFace) MetricsDescent(window *Window) int {
  2850. metric := evalErr(fmt.Sprintf("font metrics %s -displayof %s -descent", f.name, window))
  2851. return atoi(metric)
  2852. }
  2853. // NewFont — Create and inspect fonts.
  2854. //
  2855. // # Description
  2856. //
  2857. // Returns how far apart vertically in pixels two lines of text using the same font should
  2858. // be placed so that none of the characters in one line overlap any of the characters
  2859. // in the other line. This is generally the sum of the ascent above the baseline line plus
  2860. // the descent below the baseline.
  2861. //
  2862. // Additional information might be available at the [Tcl/Tk font] page.
  2863. //
  2864. // [Tcl/Tk font]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/font.html
  2865. func (f *FontFace) MetricsLinespace(window *Window) int {
  2866. metric := evalErr(fmt.Sprintf("font metrics %s -displayof %s -linespace", f.name, window))
  2867. return atoi(metric)
  2868. }
  2869. // NewFont — Create and inspect fonts.
  2870. //
  2871. // # Description
  2872. //
  2873. // Returns a boolean flag that is true if this is a fixed-width font, where each normal character
  2874. // is the same width as all the other characters, or is false if this is a proportionally-spaced font,
  2875. // where individual characters have different widths. The widths of control characters, tab characters,
  2876. // and other non-printing characters are not included when calculating this value.
  2877. //
  2878. // Additional information might be available at the [Tcl/Tk font] page.
  2879. //
  2880. // [Tcl/Tk font]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/font.html
  2881. func (f *FontFace) MetricsFixed(window *Window) bool {
  2882. metric := evalErr(fmt.Sprintf("font metrics %s -displayof %s -fixed", f.name, window))
  2883. return tclBool(metric)
  2884. }
  2885. // NewFont — Create and inspect fonts.
  2886. //
  2887. // # Description
  2888. //
  2889. // Creates a new font.
  2890. //
  2891. // The following options are supported on all platforms, and are used when
  2892. // creating/specifying a font:
  2893. //
  2894. // - [Family] name
  2895. //
  2896. // The case-insensitive font family name. Tk guarantees to support the font
  2897. // families named Courier (a monospaced “typewriter” font), Times (a serifed
  2898. // “newspaper” font), and Helvetica (a sans-serif “European” font). The most
  2899. // closely matching native font family will automatically be substituted when
  2900. // one of the above font families is used. The name may also be the name of a
  2901. // native, platform-specific font family; in that case it will work as desired
  2902. // on one platform but may not display correctly on other platforms. If the
  2903. // family is unspecified or unrecognized, a platform-specific default font will
  2904. // be chosen.
  2905. //
  2906. // - [Size] size
  2907. //
  2908. // The desired size of the font. If the size argument is a positive number, it
  2909. // is interpreted as a size in points. If size is a negative number, its
  2910. // absolute value is interpreted as a size in pixels. If a font cannot be
  2911. // displayed at the specified size, a nearby size will be chosen. If size is
  2912. // unspecified or zero, a platform-dependent default size will be chosen.
  2913. //
  2914. // Sizes should normally be specified in points so the application will remain
  2915. // the same ruler size on the screen, even when changing screen resolutions or
  2916. // moving scripts across platforms. However, specifying pixels is useful in
  2917. // certain circumstances such as when a piece of text must line up with respect
  2918. // to a fixed-size bitmap. The mapping between points and pixels is set when
  2919. // the application starts, based on properties of the installed monitor, but it
  2920. // can be overridden by calling the tk scaling command.
  2921. //
  2922. // - [Weight] weight
  2923. //
  2924. // The nominal thickness of the characters in the font. The value normal
  2925. // specifies a normal weight font, while bold specifies a bold font. The
  2926. // closest available weight to the one specified will be chosen. The default
  2927. // weight is normal.
  2928. //
  2929. // - [Slant] slant
  2930. //
  2931. // The amount the characters in the font are slanted away from the vertical.
  2932. // Valid values for slant are roman and italic. A roman font is the normal,
  2933. // upright appearance of a font, while an italic font is one that is tilted
  2934. // some number of degrees from upright. The closest available slant to the one
  2935. // specified will be chosen. The default slant is roman.
  2936. //
  2937. // - [Underline] boolean
  2938. //
  2939. // The value is a boolean flag that specifies whether characters in this font
  2940. // should be underlined. The default value for underline is false.
  2941. //
  2942. // - [Overstrike] boolean
  2943. //
  2944. // The value is a boolean flag that specifies whether a horizontal line should
  2945. // be drawn through the middle of characters in this font. The default value
  2946. // for overstrike is false.
  2947. //
  2948. // Additional information might be available at the [Tcl/Tk font] page.
  2949. //
  2950. // [Tcl/Tk font]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/font.html
  2951. func NewFont(options ...Opt) *FontFace {
  2952. nm := fmt.Sprintf("font%v", id.Add(1))
  2953. code := ""
  2954. configure := false
  2955. if name := collectOne("-family", options...); name != "" &&
  2956. strings.HasPrefix(name, "Tk") {
  2957. code = "font actual " + name
  2958. nm = name
  2959. configure = true
  2960. } else {
  2961. code = fmt.Sprintf("font create %s %s", nm, collect(options...))
  2962. }
  2963. r, err := eval(code)
  2964. if err == nil && configure {
  2965. code := fmt.Sprintf("font configure %s %s", nm, collect(options...))
  2966. r, err = eval(code)
  2967. }
  2968. if err != nil {
  2969. fail(fmt.Errorf("code=%s -> r=%s err=%v", code, r, err))
  2970. return nil
  2971. }
  2972. return &FontFace{name: nm}
  2973. }
  2974. // FontFamilies — Create and inspect fonts.
  2975. //
  2976. // # Description
  2977. //
  2978. // The return value is a list of the case-insensitive names of all font
  2979. // families that exist on window's display. If the Displayof argument is
  2980. // omitted, it defaults to the main window.
  2981. //
  2982. // - [Displayof] window
  2983. //
  2984. // Additional information might be available at the [Tcl/Tk font] page.
  2985. //
  2986. // [Tcl/Tk font]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/font.html
  2987. func FontFamilies(options ...Opt) []string {
  2988. return parseList(evalErr(fmt.Sprintf("font families %s", collect(options...))))
  2989. }
  2990. func parseList(list string) (r []string) {
  2991. if len(list) == 0 {
  2992. return nil
  2993. }
  2994. cList, err := cString(list)
  2995. if err != nil {
  2996. fail(fmt.Errorf("failed to allocate C string for list : %w", err))
  2997. return
  2998. }
  2999. defer free(cList)
  3000. var _uintptr uintptr
  3001. pointers, err := malloc(int(2 * unsafe.Sizeof(_uintptr)))
  3002. if err != nil {
  3003. fail(fmt.Errorf("failed to allocate memory for argc & argv pointers : %w", err))
  3004. return
  3005. }
  3006. defer free(pointers)
  3007. argcPtr := pointers
  3008. argvPtr := pointers + unsafe.Sizeof(_uintptr)
  3009. callSplitList(cList, argcPtr, argvPtr)
  3010. argc := *((*int)(unsafe.Pointer(argcPtr)))
  3011. argv := unsafe.Slice((*(**uintptr)(unsafe.Pointer(argvPtr))), argc)
  3012. items := make([]string, argc)
  3013. for i, arg := range argv {
  3014. items[i] = goString(arg)
  3015. }
  3016. return items
  3017. }
  3018. // Delete — Manipulate fonts.
  3019. //
  3020. // # Description
  3021. //
  3022. // Delete the font. If there are widgets using the named font, the named font
  3023. // will not actually be deleted until all the instances are released. Those
  3024. // widgets will continue to display using the last known values for the named
  3025. // font. If a deleted named font is subsequently recreated with another call to
  3026. // font create, the widgets will use the new named font and redisplay
  3027. // themselves using the new attributes of that font.
  3028. //
  3029. // Additional information might be available at the [Tcl/Tk font] page.
  3030. //
  3031. // [Tcl/Tk font]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/font.html
  3032. func (f *FontFace) Delete() {
  3033. evalErr(fmt.Sprintf("font delete %s", f))
  3034. }
  3035. // Text — Create and manipulate 'text' hypertext editing widgets
  3036. //
  3037. // # Description
  3038. //
  3039. // Inserts all of the chars arguments just before the character at index. If
  3040. // index refers to the end of the text (the character after the last newline)
  3041. // then the new text is inserted just before the last newline instead. If there
  3042. // is a single chars argument and no tagList, then the new text will receive
  3043. // any tags that are present on both the character before and the character
  3044. // after the insertion point; if a tag is present on only one of these
  3045. // characters then it will not be applied to the new text. If tagList is
  3046. // specified then it consists of a list of tag names; the new characters will
  3047. // receive all of the tags in this list and no others, regardless of the tags
  3048. // present around the insertion point. If multiple chars-tagList argument pairs
  3049. // are present, they produce the same effect as if a separate pathName insert
  3050. // widget command had been issued for each pair, in order. The last tagList
  3051. // argument may be omitted.
  3052. //
  3053. // The value that is passed to Tcl/Tk for the 'index' argument is obtained by
  3054. // fmt.Sprint(index), enabling any custom index encoding via implementing
  3055. // fmt.Stringer.
  3056. //
  3057. // # Indices
  3058. //
  3059. // Many of the widget commands for texts take one or more indices as arguments.
  3060. // An index is a string used to indicate a particular place within a text, such
  3061. // as a place to insert characters or one endpoint of a range of characters to
  3062. // delete. Indices have the syntax
  3063. //
  3064. // base modifier modifier modifier ...
  3065. //
  3066. // Where base gives a starting point and the modifiers adjust the index from
  3067. // the starting point (e.g. move forward or backward one character). Every
  3068. // index must contain a base, but the modifiers are optional. Most modifiers
  3069. // (as documented below) allow an optional submodifier. Valid submodifiers are
  3070. // any and display. If the submodifier is abbreviated, then it must be followed
  3071. // by whitespace, but otherwise there need be no space between the submodifier
  3072. // and the following modifier. Typically the display submodifier adjusts the
  3073. // meaning of the following modifier to make it refer to visual or non-elided
  3074. // units rather than logical units, but this is explained for each relevant
  3075. // case below. Lastly, where count is used as part of a modifier, it can be
  3076. // positive or negative, so “base - -3 lines” is perfectly valid (and
  3077. // equivalent to “base +3lines”).
  3078. //
  3079. // The base for an index must have one of the following forms:
  3080. //
  3081. // "line.char"
  3082. //
  3083. // Indicates char'th character on line line. Lines are numbered from 1 for
  3084. // consistency with other UNIX programs that use this numbering scheme. Within
  3085. // a line, characters are numbered from 0. If char is end then it refers to the
  3086. // newline character that ends the line.
  3087. //
  3088. // This form of index can be passed as [LC]{line, char}.
  3089. //
  3090. // "@x,y"
  3091. //
  3092. // Indicates the character that covers the pixel whose x and y coordinates
  3093. // within the text's window are x and y.
  3094. //
  3095. // "end"
  3096. //
  3097. // Indicates the end of the text (the character just after the last newline).
  3098. //
  3099. // "mark"
  3100. //
  3101. // Indicates the character just after the mark whose name is mark (see MARKS
  3102. // for details).
  3103. //
  3104. // "tag.first"
  3105. //
  3106. // Indicates the first character in the text that has been tagged with tag.
  3107. // This form generates an error if no characters are currently tagged with tag.
  3108. //
  3109. // "tag.last"
  3110. //
  3111. // Indicates the character just after the last one in the text that has been
  3112. // tagged with tag. This form generates an error if no characters are currently
  3113. // tagged with tag.
  3114. //
  3115. // "pathName"
  3116. //
  3117. // Indicates the position of the embedded window whose name is pathName. This
  3118. // form generates an error if there is no embedded window by the given name.
  3119. //
  3120. // "imageName"
  3121. //
  3122. // Indicates the position of the embedded image whose name is imageName. This
  3123. // form generates an error if there is no embedded image by the given name.
  3124. //
  3125. // If the base could match more than one of the above forms, such as a mark and
  3126. // imageName both having the same value, then the form earlier in the above
  3127. // list takes precedence. If modifiers follow the base index, each one of them
  3128. // must have one of the forms listed below. Keywords such as chars and wordend
  3129. // may be abbreviated as long as the abbreviation is unambiguous.
  3130. //
  3131. // "+ count ?submodifier? chars"
  3132. //
  3133. // Adjust the index forward by count characters, moving to later lines in the
  3134. // text if necessary. If there are fewer than count characters in the text
  3135. // after the current index, then set the index to the last index in the text.
  3136. // Spaces on either side of count are optional. If the display submodifier is
  3137. // given, elided characters are skipped over without being counted. If any is
  3138. // given, then all characters are counted. For historical reasons, if neither
  3139. // modifier is given then the count actually takes place in units of index
  3140. // positions (see INDICES for details). This behaviour may be changed in a
  3141. // future major release, so if you need an index count, you are encouraged to
  3142. // use indices instead wherever possible.
  3143. //
  3144. // "- count ?submodifier? chars"
  3145. //
  3146. // Adjust the index backward by count characters, moving to earlier lines in
  3147. // the text if necessary. If there are fewer than count characters in the text
  3148. // before the current index, then set the index to the first index in the text
  3149. // (1.0). Spaces on either side of count are optional. If the display
  3150. // submodifier is given, elided characters are skipped over without being
  3151. // counted. If any is given, then all characters are counted. For historical
  3152. // reasons, if neither modifier is given then the count actually takes place in
  3153. // units of index positions (see INDICES for details). This behavior may be
  3154. // changed in a future major release, so if you need an index count, you are
  3155. // encouraged to use indices instead wherever possible.
  3156. //
  3157. // "+ count ?submodifier? indices"
  3158. //
  3159. // Adjust the index forward by count index positions, moving to later lines in
  3160. // the text if necessary. If there are fewer than count index positions in the
  3161. // text after the current index, then set the index to the last index position
  3162. // in the text. Spaces on either side of count are optional. Note that an index
  3163. // position is either a single character or a single embedded image or embedded
  3164. // window. If the display submodifier is given, elided indices are skipped over
  3165. // without being counted. If any is given, then all indices are counted; this
  3166. // is also the default behaviour if no modifier is given.
  3167. //
  3168. // "- count ?submodifier? indices"
  3169. //
  3170. // Adjust the index backward by count index positions, moving to earlier lines
  3171. // in the text if necessary. If there are fewer than count index positions in
  3172. // the text before the current index, then set the index to the first index
  3173. // position (1.0) in the text. Spaces on either side of count are optional. If
  3174. // the display submodifier is given, elided indices are skipped over without
  3175. // being counted. If any is given, then all indices are counted; this is also
  3176. // the default behaviour if no modifier is given.
  3177. //
  3178. // "+ count ?submodifier? lines"
  3179. //
  3180. // Adjust the index forward by count lines, retaining the same character
  3181. // position within the line. If there are fewer than count lines after the line
  3182. // containing the current index, then set the index to refer to the same
  3183. // character position on the last line of the text. Then, if the line is not
  3184. // long enough to contain a character at the indicated character position,
  3185. // adjust the character position to refer to the last character of the line
  3186. // (the newline). Spaces on either side of count are optional. If the display
  3187. // submodifier is given, then each visual display line is counted separately.
  3188. // Otherwise, if any (or no modifier) is given, then each logical line (no
  3189. // matter how many times it is visually wrapped) counts just once. If the
  3190. // relevant lines are not wrapped, then these two methods of counting are
  3191. // equivalent.
  3192. //
  3193. // "- count ?submodifier? lines"
  3194. //
  3195. // Adjust the index backward by count logical lines, retaining the same
  3196. // character position within the line. If there are fewer than count lines
  3197. // before the line containing the current index, then set the index to refer to
  3198. // the same character position on the first line of the text. Then, if the line
  3199. // is not long enough to contain a character at the indicated character
  3200. // position, adjust the character position to refer to the last character of
  3201. // the line (the newline). Spaces on either side of count are optional. If the
  3202. // display submodifier is given, then each visual display line is counted
  3203. // separately. Otherwise, if any (or no modifier) is given, then each logical
  3204. // line (no matter how many times it is visually wrapped) counts just once. If
  3205. // the relevant lines are not wrapped, then these two methods of counting are
  3206. // equivalent.
  3207. //
  3208. // "?submodifier? linestart"
  3209. //
  3210. // Adjust the index to refer to the first index on the line. If the display
  3211. // submodifier is given, this is the first index on the display line, otherwise
  3212. // on the logical line.
  3213. //
  3214. // "?submodifier? lineend"
  3215. //
  3216. // Adjust the index to refer to the last index on the line (the newline). If
  3217. // the display submodifier is given, this is the last index on the display
  3218. // line, otherwise on the logical line.
  3219. //
  3220. // "?submodifier? wordstart"
  3221. //
  3222. // Adjust the index to refer to the first character of the word containing the
  3223. // current index. A word consists of any number of adjacent characters that are
  3224. // letters, digits, or underscores, or a single character that is not one of
  3225. // these. If the display submodifier is given, this only examines non-elided
  3226. // characters, otherwise all characters (elided or not) are examined.
  3227. //
  3228. // "?submodifier? wordend"
  3229. //
  3230. // Adjust the index to refer to the character just after the last one of the
  3231. // word containing the current index. If the current index refers to the last
  3232. // character of the text then it is not modified. If the display submodifier is
  3233. // given, this only examines non-elided characters, otherwise all characters
  3234. // (elided or not) are examined.
  3235. //
  3236. // If more than one modifier is present then they are applied in left-to-right
  3237. // order. For example, the index “end - 1 chars” refers to the next-to-last
  3238. // character in the text and “insert wordstart - 1 c” refers to the character
  3239. // just before the first one in the word containing the insertion cursor.
  3240. // Modifiers are applied one by one in this left to right order, and after each
  3241. // step the resulting index is constrained to be a valid index in the text
  3242. // widget. So, for example, the index “1.0 -1c +1c” refers to the index “2.0”.
  3243. //
  3244. // Where modifiers result in index changes by display lines, display chars or
  3245. // display indices, and the base refers to an index inside an elided tag, that
  3246. // base index is considered to be equivalent to the first following non-elided
  3247. // index.
  3248. //
  3249. // Insert returns its index argument.
  3250. //
  3251. // Additional information might be available at the [Tcl/Tk text] page.
  3252. //
  3253. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3254. func (w *TextWidget) Insert(index any, chars string, options ...string) any {
  3255. idx := fmt.Sprint(index)
  3256. evalErr(fmt.Sprintf("%s insert %s %s %s", w, tclSafeString(idx), tclSafeString(chars), tclSafeStrings(options...)))
  3257. return index
  3258. }
  3259. // Text — Create and manipulate 'text' hypertext editing widgets
  3260. //
  3261. // # Description
  3262. //
  3263. // This command associates a script with the tag given by tagName. Whenever the
  3264. // event sequence given by sequence occurs for a character that has been tagged
  3265. // with tagName, the script will be invoked. This widget command is similar to
  3266. // the bind command except that it operates on characters in a text rather than
  3267. // entire widgets. See the bind manual entry for complete details on the syntax
  3268. // of sequence and the substitutions performed on script before invoking it.
  3269. // A new binding is created, replacing any existing binding for the same sequence and tagName.
  3270. // The only events for which
  3271. // bindings may be specified are those related to the mouse and keyboard (such
  3272. // as Enter, Leave, Button, Motion, and Key) or virtual events. Mouse and
  3273. // keyboard event bindings for a text widget respectively use the current and
  3274. // insert marks described under MARKS above. An Enter event triggers for a tag
  3275. // when the tag first becomes present on the current character, and a Leave
  3276. // event triggers for a tag when it ceases to be present on the current
  3277. // character. Enter and Leave events can happen either because the current mark
  3278. // moved or because the character at that position changed. Note that these
  3279. // events are different than Enter and Leave events for windows. Mouse events
  3280. // are directed to the current character, while keyboard events are directed to
  3281. // the insert character. If a virtual event is used in a binding, that binding
  3282. // can trigger only if the virtual event is defined by an underlying
  3283. // mouse-related or keyboard-related event.
  3284. //
  3285. // It is possible for the current character to have multiple tags, and for each
  3286. // of them to have a binding for a particular event sequence. When this occurs,
  3287. // one binding is invoked for each tag, in order from lowest-priority to
  3288. // highest priority. If there are multiple matching bindings for a single tag,
  3289. // then the most specific binding is chosen (see the manual entry for the bind
  3290. // command for details). continue and break commands within binding scripts are
  3291. // processed in the same way as for bindings created with the bind command.
  3292. //
  3293. // If bindings are created for the widget as a whole using the bind command,
  3294. // then those bindings will supplement the tag bindings. The tag bindings will
  3295. // be invoked first, followed by bindings for the window as a whole.
  3296. //
  3297. // Additional information might be available at the [Tcl/Tk text] page.
  3298. //
  3299. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3300. func (w *TextWidget) TagBind(tag, sequence string, handler any) string {
  3301. return evalErr(fmt.Sprintf("%s tag bind %s %s %s", w, tclSafeString(tag), tclSafeString(sequence), newEventHandler("", handler).optionString(w.Window)))
  3302. }
  3303. // Text — Create and manipulate 'text' hypertext editing widgets
  3304. //
  3305. // # Description
  3306. //
  3307. // Counts the number of relevant things between the two indices. If index1 is
  3308. // after index2, the result will be a negative number (and this holds for each
  3309. // of the possible options). The actual items which are counted depend on the
  3310. // options given. The result is a list of integers, one for the result of each
  3311. // counting option given. Valid counting options are -chars, -displaychars,
  3312. // -displayindices, -displaylines, -indices, -lines, -xpixels and -ypixels. The
  3313. // default value, if no option is specified, is -indices. There is an
  3314. // additional possible option -update which is a modifier. If given (and if the
  3315. // text widget is managed by a geometry manager), then all subsequent options
  3316. // ensure that any possible out of date information is recalculated. This
  3317. // currently only has any effect for the -ypixels count (which, if -update is
  3318. // not given, will use the text widget's current cached value for each line).
  3319. // This -update option is obsoleted by pathName sync, pathName pendingsync and
  3320. // <<WidgetViewSync>>. The count options are interpreted as follows:
  3321. //
  3322. // - [Chars] Count all characters, whether elided or not. Do not count
  3323. // embedded windows or images.
  3324. // - [Displaychars] Count all non-elided characters.
  3325. // - [Displayindices] Count all non-elided characters, windows and images.
  3326. // - [Displaylines] Count all display lines (i.e. counting one for each time
  3327. // a line wraps) from the line of the first index up to, but not including
  3328. // the display line of the second index. Therefore if they are both on the
  3329. // same display line, zero will be returned. By definition displaylines are
  3330. // visible and therefore this only counts portions of actual visible lines.
  3331. // - [Indices] Count all characters and embedded windows or images (i.e.
  3332. // everything which counts in text-widget index space), whether they are
  3333. // elided or not.
  3334. // - [Lines] Count all logical lines (irrespective of wrapping) from the line
  3335. // of the first index up to, but not including the line of the second index.
  3336. // Therefore if they are both on the same line, zero will be returned.
  3337. // Logical lines are counted whether they are currently visible (non-elided)
  3338. // or not.
  3339. // - [Xpixels] Count the number of horizontal pixels from the first pixel of
  3340. // the first index to (but not including) the first pixel of the second
  3341. // index. To count the total desired width of the text widget (assuming
  3342. // wrapping is not enabled), first find the longest line and then use “.text
  3343. // count -xpixels "${line}.0" "${line}.0 lineend"”.
  3344. // - [Ypixels] Count the number of vertical pixels from the first pixel of
  3345. // the first index to (but not including) the first pixel of the second
  3346. // index. If both indices are on the same display line, zero will be
  3347. // returned. To count the total number of vertical pixels in the text widget,
  3348. // use “.text count -ypixels 1.0 end”, and to ensure this is up to date, use
  3349. // “.text count -update -ypixels 1.0 end”.
  3350. //
  3351. // The command returns a positive or negative integer corresponding to the
  3352. // number of items counted between the two indices. One such integer is
  3353. // returned for each counting option given, so a list is returned if more than
  3354. // one option was supplied. For example “.text count -xpixels -ypixels 1.3 4.5”
  3355. // is perfectly valid and will return a list of two elements.
  3356. //
  3357. // Additional information might be available at the [Tcl/Tk text] page.
  3358. //
  3359. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3360. func (w *TextWidget) Count(options ...any) []string {
  3361. return parseList(evalErr(fmt.Sprintf("%s count %s", w, collectAny(options...))))
  3362. }
  3363. // All option.
  3364. //
  3365. // Known uses:
  3366. // - [TextWidget] (command specific)
  3367. func All() Opt {
  3368. return rawOption("-all")
  3369. }
  3370. // Displayindices option.
  3371. //
  3372. // Known uses:
  3373. // - [TextWidget] (command specific)
  3374. func Displayindices() Opt {
  3375. return rawOption("-displayindices")
  3376. }
  3377. // Displaylines option.
  3378. //
  3379. // Known uses:
  3380. // - [TextWidget] (command specific)
  3381. func Displaylines() Opt {
  3382. return rawOption("-displaylines")
  3383. }
  3384. // Indices option.
  3385. //
  3386. // Known uses:
  3387. // - [TextWidget] (command specific)
  3388. func Indices() Opt {
  3389. return rawOption("-indices")
  3390. }
  3391. // Lines option.
  3392. //
  3393. // Known uses:
  3394. // - [TextWidget] (command specific)
  3395. func Lines() Opt {
  3396. return rawOption("-lines")
  3397. }
  3398. // Mark option.
  3399. //
  3400. // Known uses:
  3401. // - [TextWidget] (command specific)
  3402. func Mark() Opt {
  3403. return rawOption("-mark")
  3404. }
  3405. // Xpixels option.
  3406. //
  3407. // Known uses:
  3408. // - [TextWidget] (command specific)
  3409. func Xpixels() Opt {
  3410. return rawOption("-xpixels")
  3411. }
  3412. // Ypixels option.
  3413. //
  3414. // Known uses:
  3415. // - [TextWidget] (command specific)
  3416. func Ypixels() Opt {
  3417. return rawOption("-ypixels")
  3418. }
  3419. // Chars option.
  3420. //
  3421. // Known uses:
  3422. // - [TextWidget] (command specific)
  3423. func Chars() Opt {
  3424. return rawOption("-chars")
  3425. }
  3426. // Displaychars option.
  3427. //
  3428. // Known uses:
  3429. // - [TextWidget] (command specific)
  3430. func Displaychars() Opt {
  3431. return rawOption("-displaychars")
  3432. }
  3433. // Text — Create and manipulate 'text' hypertext editing widgets
  3434. //
  3435. // # Description
  3436. //
  3437. // Clears the undo and redo stacks.
  3438. //
  3439. // Additional information might be available at the [Tcl/Tk text] page.
  3440. //
  3441. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3442. func (w *TextWidget) EditReset() {
  3443. evalErr(fmt.Sprintf("%s edit reset", w))
  3444. }
  3445. // Text — Create and manipulate 'text' hypertext editing widgets
  3446. //
  3447. // # Description
  3448. //
  3449. // Sets the modified flag of the widget to 'v'.
  3450. //
  3451. // Additional information might be available at the [Tcl/Tk text] page.
  3452. //
  3453. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3454. func (w *TextWidget) SetModified(v bool) {
  3455. evalErr(fmt.Sprintf("%s edit modified %v", w, v))
  3456. }
  3457. // Text — Create and manipulate 'text' hypertext editing widgets
  3458. //
  3459. // # Description
  3460. //
  3461. // Returns the modified flag of the widget. The insert, delete, edit undo and
  3462. // edit redo commands or the user can set or clear the modified flag.
  3463. //
  3464. // Additional information might be available at the [Tcl/Tk text] page.
  3465. //
  3466. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3467. func (w *TextWidget) Modified() bool {
  3468. return tclBool(evalErr(fmt.Sprintf("%s edit modified", w)))
  3469. }
  3470. func tclBool(s string) bool {
  3471. switch s {
  3472. case "1", "true", "yes":
  3473. return true
  3474. case "0", "false", "no":
  3475. return false
  3476. default:
  3477. fail(fmt.Errorf("unexpected Tcl bool: %q", s))
  3478. return false
  3479. }
  3480. }
  3481. // Text — Create and manipulate 'text' hypertext editing widgets
  3482. //
  3483. // # Description
  3484. //
  3485. // Returns a list whose elements are the names of all the tags that are active
  3486. // at the character position given by index. If index is omitted, then the
  3487. // return value will describe all of the tags that exist for the text (this
  3488. // includes all tags that have been named in a “pathName tag” widget command
  3489. // but have not been deleted by a “pathName tag delete” widget command, even if
  3490. // no characters are currently marked with the tag). The list will be sorted in
  3491. // order from lowest priority to highest priority.
  3492. //
  3493. // Additional information might be available at the [Tcl/Tk text] page.
  3494. //
  3495. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3496. func (w *TextWidget) TagNames(index string) []string {
  3497. if index != "" {
  3498. index = tclSafeString(index)
  3499. }
  3500. return parseList(evalErr(fmt.Sprintf("%s tag names %s", w, index)))
  3501. }
  3502. // Text — Create and manipulate 'text' hypertext editing widgets
  3503. //
  3504. // # Description
  3505. //
  3506. // If direction is not specified, returns left or right to indicate which of
  3507. // its adjacent characters markName is attached to. If direction is specified,
  3508. // it must be left or right; the gravity of markName is set to the given value.
  3509. //
  3510. // Additional information might be available at the [Tcl/Tk text] page.
  3511. //
  3512. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3513. func (w *TextWidget) MarkGravity(markName, direction string) {
  3514. evalErr(fmt.Sprintf("%s mark gravity %s %s", w, tclSafeString(markName), tclSafeString(direction)))
  3515. }
  3516. // Text — Create and manipulate 'text' hypertext editing widgets
  3517. //
  3518. // # Description
  3519. //
  3520. // Sets the mark named markName to a position just before the character at
  3521. // index. If markName already exists, it is moved from its old position; if it
  3522. // does not exist, a new mark is created. This command returns an empty string.
  3523. //
  3524. // Additional information might be available at the [Tcl/Tk text] page.
  3525. //
  3526. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3527. func (w *TextWidget) MarkSet(markName string, index any) {
  3528. evalErr(fmt.Sprintf("%s mark set %s %s", w, tclSafeString(markName), tclSafeString(fmt.Sprint(index))))
  3529. }
  3530. // Text — Create and manipulate 'text' hypertext editing widgets
  3531. //
  3532. // # Description
  3533. //
  3534. // Remove the mark corresponding to each of the markName arguments. The removed
  3535. // marks will not be usable in indices and will not be returned by future calls
  3536. // to “pathName mark names”. This command returns an empty string.
  3537. //
  3538. // Additional information might be available at the [Tcl/Tk text] page.
  3539. //
  3540. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3541. func (w *TextWidget) MarkUnset(markName ...string) {
  3542. evalErr(fmt.Sprintf("%s mark unset %s", w, tclSafeStrings(markName...)))
  3543. }
  3544. // Text — Create and manipulate 'text' hypertext editing widgets
  3545. //
  3546. // # Description
  3547. //
  3548. // Returns a list whose elements are the names of all the marks that are
  3549. // currently set.
  3550. //
  3551. // Additional information might be available at the [Tcl/Tk text] page.
  3552. //
  3553. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3554. func (w *TextWidget) MarkNames() []string {
  3555. return parseList(evalErr(fmt.Sprintf("%s mark names", w)))
  3556. }
  3557. // Text — Create and manipulate 'text' hypertext editing widgets
  3558. //
  3559. // # Description
  3560. //
  3561. // Searches the text in pathName starting at index for a range of characters
  3562. // that matches pattern. If a match is found, the index of the first character
  3563. // in the match is returned as result; otherwise an empty string is returned.
  3564. // One or more of the following switches (or abbreviations thereof) may be
  3565. // specified to control the search:
  3566. //
  3567. // Additional information might be available at the [Tcl/Tk text] page.
  3568. //
  3569. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3570. func (w *TextWidget) Search(options ...any) string {
  3571. var switches Opts
  3572. var args []any
  3573. for _, v := range options {
  3574. switch x := v.(type) {
  3575. case Opt:
  3576. switches = append(switches, x)
  3577. default:
  3578. args = append(args, v)
  3579. }
  3580. }
  3581. return evalErr(fmt.Sprintf("%s search %s %s", w, collect(switches...), tclSafeList(args...)))
  3582. }
  3583. // Forward option.
  3584. //
  3585. // Known uses:
  3586. // - [Text] (widget specific, applies to Search)
  3587. func Forward() Opt {
  3588. return rawOption(fmt.Sprintf(`-forward`))
  3589. }
  3590. // Backward option.
  3591. //
  3592. // Known uses:
  3593. // - [Text] (widget specific, applies to Search)
  3594. func Backward() Opt {
  3595. return rawOption(fmt.Sprintf(`-backward`))
  3596. }
  3597. // Regexp option.
  3598. //
  3599. // Known uses:
  3600. // - [Text] (widget specific, applies to Search)
  3601. func Regexp() Opt {
  3602. return rawOption(fmt.Sprintf(`-regexp`))
  3603. }
  3604. // Nocase option.
  3605. //
  3606. // Known uses:
  3607. // - [Text] (widget specific, applies to Search)
  3608. func Nocase() Opt {
  3609. return rawOption(fmt.Sprintf(`-nocase`))
  3610. }
  3611. // Text — Create and manipulate 'text' hypertext editing widgets
  3612. //
  3613. // # Description
  3614. //
  3615. // Deletes all tag information for each of the tagName arguments. The command
  3616. // removes the tags from all characters in the file and also deletes any other
  3617. // information associated with the tags, such as bindings and display
  3618. // information. The command returns an empty string.
  3619. //
  3620. // Additional information might be available at the [Tcl/Tk text] page.
  3621. //
  3622. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3623. func (w *TextWidget) TagDelete(tags ...string) {
  3624. evalErr(fmt.Sprintf("%s tag delete %s", w, tclSafeStrings(tags...)))
  3625. }
  3626. // Text — Create and manipulate 'text' hypertext editing widgets
  3627. //
  3628. // # Description
  3629. //
  3630. // Clear makes 'w' empty.
  3631. func (w *TextWidget) Clear() {
  3632. w.Delete("0.0", "end")
  3633. w.TagDelete(w.TagNames("")...)
  3634. w.MarkUnset(w.MarkNames()...)
  3635. }
  3636. // Text — Create and manipulate 'text' hypertext editing widgets
  3637. //
  3638. // # Description
  3639. //
  3640. // Copies the selection in the widget to the clipboard, if there is a selection.
  3641. //
  3642. // Additional information might be available at the [Tcl/Tk text] page.
  3643. //
  3644. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3645. func (w *TextWidget) Copy() {
  3646. evalErr(fmt.Sprintf("tk_textCopy %s", w))
  3647. }
  3648. // Text — Create and manipulate 'text' hypertext editing widgets
  3649. //
  3650. // # Description
  3651. //
  3652. // Copies the selection in the widget to the clipboard and deletes the
  3653. // selection. If there is no selection in the widget then these keys have no
  3654. // effect.
  3655. //
  3656. // Additional information might be available at the [Tcl/Tk text] page.
  3657. //
  3658. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3659. func (w *TextWidget) Cut() {
  3660. evalErr(fmt.Sprintf("tk_textCut %s", w))
  3661. }
  3662. // Text — Create and manipulate 'text' hypertext editing widgets
  3663. //
  3664. // # Description
  3665. //
  3666. // Inserts the contents of the clipboard at the position of the insertion cursor.
  3667. //
  3668. // Additional information might be available at the [Tcl/Tk text] page.
  3669. //
  3670. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3671. func (w *TextWidget) Paste() {
  3672. evalErr(fmt.Sprintf("tk_textPaste %s", w))
  3673. }
  3674. // Text — Create and manipulate 'text' hypertext editing widgets
  3675. //
  3676. // # Description
  3677. //
  3678. // Undoes the last edit action when the -undo option is true, and returns a
  3679. // list of indices indicating what ranges were changed by the undo operation.
  3680. // An edit action is defined as all the insert and delete commands that are
  3681. // recorded on the undo stack in between two separators. Generates an error
  3682. // when the undo stack is empty. Does nothing when the -undo option is false.
  3683. //
  3684. // Additional information might be available at the [Tcl/Tk text] page.
  3685. //
  3686. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3687. func (w *TextWidget) Undo() {
  3688. evalErr(fmt.Sprintf("%s edit undo", w))
  3689. }
  3690. // Text — Create and manipulate 'text' hypertext editing widgets
  3691. //
  3692. // # Description
  3693. //
  3694. // When the -undo option is true, reapplies the last undone edits provided no
  3695. // other edits were done since then, and returns a list of indices indicating
  3696. // what ranges were changed by the redo operation. Generates an error when the
  3697. // redo stack is empty. Does nothing when the -undo option is false.
  3698. //
  3699. // Additional information might be available at the [Tcl/Tk text] page.
  3700. //
  3701. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3702. func (w *TextWidget) Redo() {
  3703. evalErr(fmt.Sprintf("%s edit redo", w))
  3704. }
  3705. // Text — Create and manipulate 'text' hypertext editing widgets
  3706. //
  3707. // # Description
  3708. //
  3709. // Return a range of characters from the text. The return value will be all the
  3710. // characters in the text starting with the one whose index is index1 and
  3711. // ending just before the one whose index is index2 (the character at index2
  3712. // will not be returned). If index2 is omitted then the single character at
  3713. // index1 is returned. If there are no characters in the specified range (e.g.
  3714. // index1 is past the end of the file or index2 is less than or equal to
  3715. // index1) then an empty string is returned. If the specified range contains
  3716. // embedded windows, no information about them is included in the returned
  3717. // string. If multiple index pairs are given, multiple ranges of text will be
  3718. // returned in a list. Invalid ranges will not be represented with empty
  3719. // strings in the list. The ranges are returned in the order passed to pathName
  3720. // get. If the -displaychars option is given, then, within each range, only
  3721. // those characters which are not elided will be returned. This may have the
  3722. // effect that some of the returned ranges are empty strings.
  3723. //
  3724. // BUG(jnml) [TextWidget.Get] currently supports only one range.
  3725. //
  3726. // Additional information might be available at the [Tcl/Tk text] page.
  3727. //
  3728. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3729. func (w *TextWidget) Get(options ...any) (r []string) {
  3730. return []string{evalErr(fmt.Sprintf("%s get %s", w, collectAny(options...)))}
  3731. }
  3732. // Text is a shortcut for w.Get("1.0", "end-1c")[0].
  3733. func (w *TextWidget) Text() string {
  3734. return w.Get("1.0", "end-1c")[0]
  3735. }
  3736. // Text — Create and manipulate 'text' hypertext editing widgets
  3737. //
  3738. // # Description
  3739. //
  3740. // Replaces the range of characters between index1 and index2 with the given
  3741. // characters and tags. See the section on pathName insert for an explanation
  3742. // of the handling of the tagList... arguments, and the section on pathName delete
  3743. // for an explanation of the handling of the indices. If index2 corresponds to
  3744. // an index earlier in the text than index1, an error will be generated.
  3745. //
  3746. // The deletion and insertion are arranged so that no unnecessary scrolling of
  3747. // the window or movement of insertion cursor occurs. In addition the undo/redo
  3748. // stack are correctly modified, if undo operations are active in the text widget.
  3749. // The command returns an empty string.
  3750. //
  3751. // Additional information might be available at the [Tcl/Tk text] page.
  3752. //
  3753. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3754. func (w *TextWidget) Replace(index1 any, index2 any, chars string, options ...any) string {
  3755. return evalErr(fmt.Sprintf("%s replace %s %s %s %s", w,
  3756. tclSafeString(fmt.Sprint(index1)),
  3757. tclSafeString(fmt.Sprint(index2)),
  3758. tclSafeString(chars),
  3759. collectAny(options...),
  3760. ))
  3761. }
  3762. // Text — Create and manipulate 'text' hypertext editing widgets
  3763. //
  3764. // # Description
  3765. //
  3766. // Return the contents of the text widget from index1 up to, but not including
  3767. // index2, including the text and information about marks, tags, and embedded
  3768. // windows. If index2 is not specified, then it defaults to one character past
  3769. // index1. The information is returned in the following format:
  3770. //
  3771. // key1 value1 index1 key2 value2 index2 ...
  3772. //
  3773. // The possible key values are text, mark, tagon, tagoff, image, and window.
  3774. // The corresponding value is the text, mark name, tag name, image name, or
  3775. // window name. The index information is the index of the start of the text,
  3776. // mark, tag transition, image or window. One or more of the following switches
  3777. // (or abbreviations thereof) may be specified to control the dump:
  3778. //
  3779. // - [All] Return information about all elements: text, marks, tags, images and windows.
  3780. // This is the default.
  3781. // - [Command command] Instead of returning the information as the result of the
  3782. // dump operation, invoke the command on each element of the text widget within the range. The command has three arguments appended to it before it is evaluated: the key, value, and index.
  3783. // - [Image] Include information about images in the dump results.
  3784. // - [Mark] Include information about marks in the dump results.
  3785. // - [Tag] Include information about tag transitions in the dump results. Tag
  3786. // information is returned as tagon and tagoff elements that indicate the begin
  3787. // and end of each range of each tag, respectively.
  3788. // - [Text] Include information about text in the dump results. The value is the
  3789. // text up to the next element or the end of range indicated by index2. A text
  3790. // element does not span newlines. A multi-line block of text that contains no
  3791. // marks or tag transitions will still be dumped as a set of text segments that
  3792. // each end with a newline. The newline is part of the value.
  3793. // - [Window] Include information about embedded windows in the dump results. The
  3794. // value of a window is its Tk pathname, unless the window has not been created yet.
  3795. // (It must have a create script.) In this case an empty string is returned, and you
  3796. // must query the window by its index position to get more information.
  3797. //
  3798. // Additional information might be available at the [Tcl/Tk text] page.
  3799. //
  3800. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3801. func (w *TextWidget) Dump(options ...any) []string {
  3802. return parseList(evalErr(fmt.Sprintf("%s dump %s", w, collectAny(options...))))
  3803. }
  3804. // LC encodes a text index consisting of a line and char number.
  3805. type LC struct {
  3806. Line int // 1-based line number within the text content.
  3807. Char int // 0-based char number within the line.
  3808. }
  3809. // String implements fmt.Stringer.
  3810. func (lc LC) String() string {
  3811. return fmt.Sprintf("%d.%d", lc.Line, lc.Char)
  3812. }
  3813. // Text — Create and manipulate 'text' hypertext editing widgets
  3814. //
  3815. // # Description
  3816. //
  3817. // This command creates a new image annotation, which will appear in the text
  3818. // at the position given by index. Any number of option-value pairs may be
  3819. // specified to configure the annotation. Returns a unique identifier that may
  3820. // be used as an index to refer to this image. See EMBEDDED IMAGES for
  3821. // information on the options that are supported, and a description of the
  3822. // identifier returned.
  3823. //
  3824. // Additional information might be available at the [Tcl/Tk text] page.
  3825. //
  3826. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3827. func (w *TextWidget) ImageCreate(index any, options ...Opt) {
  3828. idx := fmt.Sprint(index)
  3829. evalErr(fmt.Sprintf("%s image create %s %s", w, tclSafeString(idx), collect(options...)))
  3830. }
  3831. // Text — Create and manipulate 'text' hypertext editing widgets
  3832. //
  3833. // # Description
  3834. //
  3835. // This command creates a new window annotation, which will appear in the text
  3836. // at the position given by index. Any number of option-value pairs may be
  3837. // specified to configure the annotation. See EMBEDDED WINDOWS for information
  3838. // on the options that are supported. Returns an empty string.
  3839. //
  3840. // Additional information might be available at the [Tcl/Tk text] page.
  3841. //
  3842. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3843. func (w *TextWidget) WindowCreate(index any, options ...Opt) {
  3844. idx := fmt.Sprint(index)
  3845. evalErr(fmt.Sprintf("%s window create %s %s", w, tclSafeString(idx), collect(options...)))
  3846. }
  3847. // Win option.
  3848. //
  3849. // Known uses:
  3850. // - [Text] (widget specific, applies to embedded windows)
  3851. func Win(val any) Opt {
  3852. return rawOption(fmt.Sprintf(`-window %s`, optionString(val)))
  3853. }
  3854. // Text — Create and manipulate 'text' hypertext editing widgets
  3855. //
  3856. // # Description
  3857. //
  3858. // Returns a list containing two elements, both of which are real fractions
  3859. // between 0 and 1. The first element gives the position of the first visible
  3860. // pixel of the first character (or image, etc) in the top line in the window,
  3861. // relative to the text as a whole (0.5 means it is halfway through the text,
  3862. // for example). The second element gives the position of the first pixel just
  3863. // after the last visible one in the bottom line of the window, relative to the
  3864. // text as a whole. These are the same values passed to scrollbars via the
  3865. // -yscrollcommand option.
  3866. //
  3867. // Additional information might be available at the [Tcl/Tk text] page.
  3868. //
  3869. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3870. func (w *TextWidget) Yview() string {
  3871. return evalErr(fmt.Sprintf("%s yview", w))
  3872. }
  3873. // Text — Create and manipulate 'text' hypertext editing widgets
  3874. //
  3875. // # Description
  3876. //
  3877. // Adjusts the view in the window so that the pixel given by fraction appears
  3878. // at the top of the top line of the window. Fraction is a fraction between 0
  3879. // and 1; 0 indicates the first pixel of the first character in the text, 0.33
  3880. // indicates the pixel that is one-third the way through the text; and so on.
  3881. // Values close to 1 will indicate values close to the last pixel in the text
  3882. // (1 actually refers to one pixel beyond the last pixel), but in such cases
  3883. // the widget will never scroll beyond the last pixel, and so a value of 1 will
  3884. // effectively be rounded back to whatever fraction ensures the last pixel is
  3885. // at the bottom of the window, and some other pixel is at the top.
  3886. //
  3887. // Additional information might be available at the [Tcl/Tk text] page.
  3888. //
  3889. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3890. func (w *TextWidget) Yviewmoveto(fraction any) string {
  3891. return evalErr(fmt.Sprintf("%s yview moveto %s", w, tclSafeString(fmt.Sprint(fraction))))
  3892. }
  3893. // Text — Create and manipulate 'text' hypertext editing widgets
  3894. //
  3895. // # Description
  3896. //
  3897. // Adjusts the view in the window so that the character given by index is
  3898. // completely visible. If index is already visible then the command does
  3899. // nothing. If index is a short distance out of view, the command adjusts the
  3900. // view just enough to make index visible at the edge of the window. If index
  3901. // is far out of view, then the command centers index in the window.
  3902. //
  3903. // Additional information might be available at the [Tcl/Tk text] page.
  3904. //
  3905. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3906. func (w *TextWidget) See(index any) {
  3907. evalErr(fmt.Sprintf("%s see %s", w, tclSafeString(fmt.Sprint(index))))
  3908. }
  3909. // Text — Create and manipulate 'text' hypertext editing widgets
  3910. //
  3911. // # Description
  3912. //
  3913. // Returns a list describing all of the ranges of text that have been tagged
  3914. // with tagName. The first two elements of the list describe the first tagged
  3915. // range in the text, the next two elements describe the second range, and so
  3916. // on. The first element of each pair contains the index of the first character
  3917. // of the range, and the second element of the pair contains the index of the
  3918. // character just after the last one in the range. If there are no characters
  3919. // tagged with tag then an empty string is returned.
  3920. //
  3921. // Additional information might be available at the [Tcl/Tk text] page.
  3922. //
  3923. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3924. func (w *TextWidget) TagRanges(tagName string) (r []string) {
  3925. return parseList(evalErr(fmt.Sprintf("%s tag ranges %s", w, tclSafeString(tagName))))
  3926. }
  3927. // Text — Create and manipulate 'text' hypertext editing widgets
  3928. //
  3929. // # Description
  3930. //
  3931. // Returns the position corresponding to index in the form line.char where line
  3932. // is the line number and char is the character number. Index may have any of
  3933. // the forms described under INDICES above.
  3934. //
  3935. // Additional information might be available at the [Tcl/Tk text] page.
  3936. //
  3937. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3938. func (w *TextWidget) Index(index any) (r string) {
  3939. return evalErr(fmt.Sprintf("%s index %s", w, tclSafeString(fmt.Sprint(index))))
  3940. }
  3941. // Text — Create and manipulate 'text' hypertext editing widgets
  3942. //
  3943. // # Description
  3944. //
  3945. // Returns a list containing two elements, both of which are real fractions
  3946. // between 0 and 1. The first element gives the position of the first visible
  3947. // pixel of the first character (or image, etc) in the top line in the window,
  3948. // relative to the text as a whole (0.5 means it is halfway through the text,
  3949. // for example). The second element gives the position of the first pixel just
  3950. // after the last visible one in the bottom line of the window, relative to the
  3951. // text as a whole. These are the same values passed to scrollbars via the
  3952. // -xscrollcommand option.
  3953. //
  3954. // Additional information might be available at the [Tcl/Tk text] page.
  3955. //
  3956. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3957. func (w *TextWidget) Xview() string {
  3958. return evalErr(fmt.Sprintf("%s xview", w))
  3959. }
  3960. // Text — Create and manipulate 'text' hypertext editing widgets
  3961. //
  3962. // # Description
  3963. //
  3964. // This command is similar to the pathName configure widget command except that
  3965. // it modifies options associated with the tag given by tagName instead of
  3966. // modifying options for the overall text widget. If no option is specified,
  3967. // the command returns a list describing all of the available options for
  3968. // tagName (see Tk_ConfigureInfo for information on the format of this list).
  3969. // If option is specified with no value, then the command returns a list
  3970. // describing the one named option (this list will be identical to the
  3971. // corresponding sublist of the value returned if no option is specified). If
  3972. // one or more option-value pairs are specified, then the command modifies the
  3973. // given option(s) to have the given value(s) in tagName; in this case the
  3974. // command returns an empty string. See TAGS above for details on the options
  3975. // available for tags.
  3976. //
  3977. // Additional information might be available at the [Tcl/Tk text] page.
  3978. //
  3979. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  3980. func (w *TextWidget) TagConfigure(tagName string, options ...Opt) {
  3981. evalErr(fmt.Sprintf("%s tag configure %s %s", w, tclSafeString(tagName), collect(options...)))
  3982. }
  3983. // Text — Create and manipulate 'text' hypertext editing widgets
  3984. //
  3985. // # Description
  3986. //
  3987. // Select all text in 'w'.
  3988. func (w *TextWidget) SelectAll() {
  3989. evalErr(fmt.Sprintf("%s tag add sel 1.0 end", w))
  3990. }
  3991. // Text — Create and manipulate 'text' hypertext editing widgets
  3992. //
  3993. // # Description
  3994. //
  3995. // Associate the tag name with all of the characters starting with index1
  3996. // and ending just before index2 (the character at index2 is not tagged). A
  3997. // single command may contain any number of index1-index2 pairs. If the last
  3998. // index2 is omitted then the single character at index1 is tagged. If there
  3999. // are no characters in the specified range (e.g. index1 is past the end of the
  4000. // file or index2 is less than or equal to index1) then the command has no
  4001. // effect.
  4002. //
  4003. // Additional information might be available at the [Tcl/Tk text] page.
  4004. //
  4005. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  4006. func (w *TextWidget) TagAdd(tagName string, indexes ...any) string {
  4007. evalErr(fmt.Sprintf("%s tag add %s %s", w, tclSafeString(tagName), collectAny(indexes...)))
  4008. return tagName
  4009. }
  4010. // Text — Create and manipulate 'text' hypertext editing widgets
  4011. //
  4012. // # Description
  4013. //
  4014. // Remove the tag tagName from all of the characters starting at index1 and
  4015. // ending just before index2 (the character at index2 is not affected). A single
  4016. // command may contain any number of index1-index2 pairs. If the last index2 is
  4017. // omitted then the tag is removed from the single character at index1. If there
  4018. // are no characters in the specified range (e.g. index1 is past the end of the
  4019. // file or index2 is less than or equal to index1) then the command has no effect.
  4020. // This command returns an empty string.
  4021. //
  4022. // Additional information might be available at the [Tcl/Tk text] page.
  4023. //
  4024. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  4025. func (w *TextWidget) TagRemove(tagName string, indexes ...any) string {
  4026. return evalErr(fmt.Sprintf("%s tag remove %s %s", w, tclSafeString(tagName), collectAny(indexes...)))
  4027. }
  4028. // Text — Create and manipulate 'text' hypertext editing widgets
  4029. //
  4030. // # Description
  4031. //
  4032. // Delete a range of characters from the text. If both index1 and index2 are
  4033. // specified, then delete all the characters starting with the one given by
  4034. // index1 and stopping just before index2 (i.e. the character at index2 is not
  4035. // deleted). If index2 does not specify a position later in the text than
  4036. // index1 then no characters are deleted. If index2 is not specified then the
  4037. // single character at index1 is deleted. Attempts to delete characters in a
  4038. // way that would leave the text without a newline as the last character will
  4039. // be tweaked by the text widget to avoid this. In particular, deletion of
  4040. // complete lines of text up to the end of the text will also delete the
  4041. // newline character just before the deleted block so that it is replaced by
  4042. // the new final newline of the text widget. The command returns an empty
  4043. // string. If more indices are given, multiple ranges of text will be deleted.
  4044. // All indices are first checked for validity before any deletions are made.
  4045. // They are sorted and the text is removed from the last range to the first
  4046. // range so deleted text does not cause an undesired index shifting
  4047. // side-effects. If multiple ranges with the same start index are given, then
  4048. // the longest range is used. If overlapping ranges are given, then they will
  4049. // be merged into spans that do not cause deletion of text outside the given
  4050. // ranges due to text shifted during deletion.
  4051. //
  4052. // Additional information might be available at the [Tcl/Tk text] page.
  4053. //
  4054. // [Tcl/Tk text]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/text.html
  4055. func (w *TextWidget) Delete(options ...any) {
  4056. evalErr(fmt.Sprintf("%s delete %s", w, collectAny(options...)))
  4057. }
  4058. // Text — Create and manipulate 'text' hypertext editing widgets
  4059. //
  4060. // # Description
  4061. //
  4062. // InsertML inserts 'ml' at the end of 'w', interpreting it as a HTML-like
  4063. // markup language.
  4064. //
  4065. // It recognizes and treats accordingly the <br> tag.
  4066. //
  4067. // The <img> tag is reserved for embedded images. You can inline the image
  4068. // directly:
  4069. //
  4070. // InsertML("Hello", NewPhoto(...), Align("top"), "world!")
  4071. //
  4072. // The <embed> tag is reserved for embedded widgets. You can inline a widget
  4073. // directly:
  4074. //
  4075. // InsertML("Hello", Button(Txt("Foo")), Align("center"), "world!")
  4076. //
  4077. // The <pre> tag works similarly to HTML, ie. white space and line breaks are
  4078. // kept. To make the content of a <pre> rendered in monospace, configure the
  4079. // tag, for example:
  4080. //
  4081. // t.TagConfigure("pre", Font(CourierFont(), 10)
  4082. //
  4083. // Other ML-tags are used as names of configured 'w' tags, if configured,
  4084. // ignored otherwise.
  4085. //
  4086. // Example usage in _examples/embed.go.
  4087. func (w *TextWidget) InsertML(list ...any) {
  4088. var ml bytes.Buffer
  4089. for i := 0; i < len(list); i++ {
  4090. switch x := list[i].(type) {
  4091. case string:
  4092. ml.WriteString(x)
  4093. case *Img:
  4094. var opts Opts
  4095. for j := i + 1; j < len(list); j++ {
  4096. x, ok := list[j].(Opt)
  4097. if !ok {
  4098. break
  4099. }
  4100. opts = append(opts, x)
  4101. }
  4102. fmt.Fprintf(&ml, "<img src=%q", x)
  4103. for _, v := range opts {
  4104. fmt.Fprintf(&ml, " opt=%q", v.optionString(w.Window))
  4105. i++
  4106. }
  4107. ml.WriteString(">")
  4108. case Widget:
  4109. var opts Opts
  4110. for j := i + 1; j < len(list); j++ {
  4111. x, ok := list[j].(Opt)
  4112. if !ok {
  4113. break
  4114. }
  4115. opts = append(opts, x)
  4116. }
  4117. fmt.Fprintf(&ml, "<embed src=%q", x)
  4118. for _, v := range opts {
  4119. fmt.Fprintf(&ml, " opt=%q", v.optionString(w.Window))
  4120. i++
  4121. }
  4122. ml.WriteString(">")
  4123. }
  4124. }
  4125. doc, err := html.Parse(&ml)
  4126. if err != nil {
  4127. fail(err)
  4128. return
  4129. }
  4130. var tags []string
  4131. var body int
  4132. k := TkScaling() * 72 / 600
  4133. walk(0, doc, func(lvl int, n *html.Node) bool {
  4134. switch n.Type {
  4135. case html.TextNode:
  4136. if lvl < len(tags) {
  4137. tags = tags[:lvl]
  4138. }
  4139. tags := tags[body+1:]
  4140. for _, v := range tags {
  4141. if v == "pre" {
  4142. evalErr(fmt.Sprintf("%s insert end %s %s", w, tclSafeString(unescapeML(n.Data)), tclSafeStrings(tags...)))
  4143. return true
  4144. }
  4145. }
  4146. ids, toks := tokenize(n.Data)
  4147. for i, id := range ids {
  4148. switch id {
  4149. default:
  4150. if s := toks[i]; strings.HasPrefix(s, "$$") && strings.HasSuffix(s, "$$") || strings.HasPrefix(s, "$") && strings.HasSuffix(s, "$") {
  4151. img := NewPhoto(Data(TeX(s, k)))
  4152. evalErr(fmt.Sprintf("%v image create end -image %s -align top", w, img))
  4153. break
  4154. }
  4155. fallthrough
  4156. case 0:
  4157. evalErr(fmt.Sprintf("%s insert end %s {%s}", w, tclFromElementNode(unescapeML(toks[i])), tclSafeStrings(tags...)))
  4158. }
  4159. }
  4160. case html.ElementNode:
  4161. switch n.Data {
  4162. case "br":
  4163. evalErr(fmt.Sprintf("%s insert end \\n {%s}", w, tclSafeStrings(tags...)))
  4164. case "body":
  4165. tags = append(tags, n.Data)
  4166. body = lvl
  4167. case "img":
  4168. var src string
  4169. var opts []string
  4170. for _, v := range n.Attr {
  4171. switch v.Key {
  4172. case "src":
  4173. src = v.Val
  4174. case "opt":
  4175. opts = append(opts, v.Val)
  4176. }
  4177. }
  4178. evalErr(fmt.Sprintf("%v image create end -image %s %s", w, src, strings.Join(opts, " ")))
  4179. case "embed":
  4180. var src string
  4181. var opts []string
  4182. for _, v := range n.Attr {
  4183. switch v.Key {
  4184. case "src":
  4185. src = v.Val
  4186. case "opt":
  4187. opts = append(opts, v.Val)
  4188. }
  4189. }
  4190. evalErr(fmt.Sprintf("%v window create end -window %s %s", w, src, strings.Join(opts, " ")))
  4191. default:
  4192. if lvl < len(tags) {
  4193. tags = tags[:lvl]
  4194. }
  4195. tags = append(tags, n.Data)
  4196. }
  4197. }
  4198. return true
  4199. })
  4200. }
  4201. func unescapeML(s string) string {
  4202. s = strings.ReplaceAll(s, "\\$", "$")
  4203. s = strings.ReplaceAll(s, "&lt;", "<")
  4204. s = strings.ReplaceAll(s, "&gt;", ">")
  4205. return s
  4206. }
  4207. func tokenize(s string) (ids []int, toks []string) {
  4208. for {
  4209. id, len := mlToken(s)
  4210. if len == 0 {
  4211. return ids, toks
  4212. }
  4213. ids = append(ids, id)
  4214. toks = append(toks, s[:len])
  4215. s = s[len:]
  4216. }
  4217. }
  4218. func tclFromElementNode(s string) string {
  4219. a := strings.Fields(s)
  4220. var prefix, suffix string
  4221. if s != "" {
  4222. switch s[0] {
  4223. case '\n', ' ', '\t':
  4224. prefix = " "
  4225. }
  4226. switch s[len(s)-1] {
  4227. case '\n', ' ', '\t':
  4228. suffix = " "
  4229. }
  4230. }
  4231. return tclBinaryString(fmt.Sprintf("%s%s%s", prefix, strings.Join(a, " "), suffix))
  4232. }
  4233. var badMLChars = [...]bool{
  4234. '}': true,
  4235. '\\': true,
  4236. '\n': true,
  4237. '\r': true,
  4238. '\t': true,
  4239. }
  4240. // Align option.
  4241. //
  4242. // Known uses:
  4243. // - [Text] (widget specific, applies to embedded images)
  4244. func Align(val any) Opt {
  4245. return rawOption(fmt.Sprintf(`-align %s`, optionString(val)))
  4246. }
  4247. func walk(lvl int, n *html.Node, visitor func(lvl int, n *html.Node) (dive bool)) {
  4248. for ; n != nil; n = n.NextSibling {
  4249. if visitor(lvl, n) {
  4250. walk(lvl+1, n.FirstChild, visitor)
  4251. }
  4252. }
  4253. }
  4254. // Fontchooser — control font selection dialog
  4255. //
  4256. // # Description
  4257. //
  4258. // The tk fontchooser command controls the Tk font selection dialog. It uses
  4259. // the native platform font selection dialog where available, or a dialog
  4260. // implemented in Tcl otherwise.
  4261. //
  4262. // Unlike most of the other Tk dialog commands, tk fontchooser does not return
  4263. // an immediate result, as on some platforms (Mac OS X) the standard font
  4264. // dialog is modeless while on others (Windows) it is modal. To get the
  4265. // user-selected font use FontchooserFont() from a handler assigned via
  4266. // [Command].
  4267. //
  4268. // Set one or more of the configurations options below (analogous to Tk widget configuration).
  4269. //
  4270. // - [Parent]
  4271. //
  4272. // Specifies/returns the logical parent window of the font selection dialog
  4273. // (similar to the -parent option to other dialogs). The font selection dialog
  4274. // is hidden if it is visible when the parent window is destroyed.
  4275. //
  4276. // - [Title]
  4277. //
  4278. // Specifies/returns the title of the dialog. Has no effect on platforms where
  4279. // the font selection dialog does not support titles.
  4280. //
  4281. // - [FontFace]
  4282. //
  4283. // Specifies/returns the font that is currently selected in the dialog if it is
  4284. // visible, or that will be initially selected when the dialog is shown (if
  4285. // supported by the platform). Can be set to the empty string to indicate that
  4286. // no font should be selected. Fonts can be specified in any form given by the
  4287. // "FONT DESCRIPTION" section in the font manual page.
  4288. //
  4289. // - [Command]
  4290. //
  4291. // Specifies the command called when a font selection has been made by the
  4292. // user. To obtain the font description, call [FontchooserFont] from the
  4293. // handler.
  4294. //
  4295. // Additional information might be available at the [Tcl/Tk fontchooser] page.
  4296. //
  4297. // [Tcl/Tk fontchooser]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/fontchooser.html
  4298. func Fontchooser(options ...Opt) {
  4299. evalErr(fmt.Sprintf("tk fontchooser configure %s", collect(options...)))
  4300. }
  4301. // FontchooserFont — control font selection dialog
  4302. //
  4303. // # Description
  4304. //
  4305. // Returns the selected font description in the form
  4306. //
  4307. // family size style...
  4308. //
  4309. // Additional information might be available at the [Tcl/Tk fontchooser] page.
  4310. //
  4311. // [Tcl/Tk fontchooser]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/fontchooser.html
  4312. func FontchooserFont() []string {
  4313. return parseList(evalErr("tk fontchooser config -font"))
  4314. }
  4315. // FontchooserShow — control font selection dialog
  4316. //
  4317. // # Description
  4318. //
  4319. // Show the font selection dialog. Depending on the platform, may return
  4320. // immediately or only once the dialog has been withdrawn.
  4321. //
  4322. // Additional information might be available at the [Tcl/Tk fontchooser] page.
  4323. //
  4324. // [Tcl/Tk fontchooser]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/fontchooser.html
  4325. func FontchooserShow() {
  4326. evalErr("tk fontchooser show")
  4327. }
  4328. // FontchooserHide — control font selection dialog
  4329. //
  4330. // # Description
  4331. //
  4332. // Hide the font selection dialog if it is visible and cause any pending tk
  4333. // fontchooser show command to return.
  4334. //
  4335. // Additional information might be available at the [Tcl/Tk fontchooser] page.
  4336. //
  4337. // [Tcl/Tk fontchooser]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/fontchooser.html
  4338. func FontchooserHide() {
  4339. evalErr("tk fontchooser hide")
  4340. }
  4341. // GetOpenFile — pop up a dialog box for the user to select a file to open.
  4342. //
  4343. // # Description
  4344. //
  4345. // GetOpenFile pops up a dialog box for the user to select a file to open. The
  4346. // function is usually associated with the Open command in the File menu. Its
  4347. // purpose is for the user to select an existing file only. If the user enters
  4348. // a non-existent file, the dialog box gives the user an error prompt and
  4349. // requires the user to give an alternative selection. If an application allows
  4350. // the user to create new files, it should do so by providing a separate New
  4351. // menu command.
  4352. //
  4353. // - [Defaultextension] extension
  4354. //
  4355. // Specifies a string that will be appended to the filename if the user enters
  4356. // a filename without an extension. The default value is the empty string,
  4357. // which means no extension will be appended to the filename in any case. This
  4358. // option is ignored on Mac OS X, which does not require extensions to
  4359. // filenames, and the UNIX implementation guesses reasonable values for this
  4360. // from the -filetypes option when this is not supplied.
  4361. //
  4362. // - [Filetypes] filePatternList ([][FileType])
  4363. //
  4364. // If a File types listbox exists in the file dialog on the particular
  4365. // platform, this option gives the filetypes in this listbox. When the user
  4366. // choose a filetype in the listbox, only the files of that type are listed. If
  4367. // this option is unspecified, or if it is set to the empty list, or if the
  4368. // File types listbox is not supported by the particular platform then all
  4369. // files are listed regardless of their types. See the section SPECIFYING FILE
  4370. // PATTERNS below for a discussion on the contents of filePatternList.
  4371. //
  4372. // - [Initialdir] directory
  4373. //
  4374. // Specifies that the files in directory should be displayed when the dialog
  4375. // pops up. If this parameter is not specified, the initial directory defaults
  4376. // to the current working directory on non-Windows systems and on Windows
  4377. // systems prior to Vista. On Vista and later systems, the initial directory
  4378. // defaults to the last user-selected directory for the application. If the
  4379. // parameter specifies a relative path, the return value will convert the
  4380. // relative path to an absolute path.
  4381. //
  4382. // - [Initialfile] filename
  4383. //
  4384. // Specifies a filename to be displayed in the dialog when it pops up.
  4385. //
  4386. // - [Multiple] boolean
  4387. //
  4388. // Allows the user to choose multiple files from the Open dialog.
  4389. //
  4390. // - [Parent] window
  4391. //
  4392. // Makes window the logical parent of the file dialog. The file dialog is
  4393. // displayed on top of its parent window. On Mac OS X, this turns the file
  4394. // dialog into a sheet attached to the parent window.
  4395. //
  4396. // - [Title] titleString
  4397. //
  4398. // Specifies a string to display as the title of the dialog box. If this option
  4399. // is not specified, then a default title is displayed.
  4400. //
  4401. // Additional information might be available at the [Tcl/Tk getopenfile] page.
  4402. //
  4403. // [Tcl/Tk getopenfile]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/getOpenFile.html
  4404. func GetOpenFile(options ...Opt) (r []string) {
  4405. return parseList(evalErr(fmt.Sprintf("tk_getOpenFile %s", collect(options...))))
  4406. }
  4407. // FileType specifies a single file type for the [Filetypes] option.
  4408. type FileType struct {
  4409. TypeName string // Eg. "Go files"
  4410. Extensions []string // Eg. []string{".go"}
  4411. MacType string // Eg. "TEXT"
  4412. }
  4413. // GetSaveFile — pop up a dialog box for the user to select a file to save.
  4414. //
  4415. // # Description
  4416. //
  4417. // GetSaveFile pops up a dialog box for the user to select a file to save.
  4418. //
  4419. // The functio is usually associated with the Save as command in the File menu.
  4420. // If the user enters a file that already exists, the dialog box prompts the
  4421. // user for confirmation whether the existing file should be overwritten or
  4422. // not.
  4423. //
  4424. // - [Confirmoverwrite] boolean
  4425. //
  4426. // Configures how the Save dialog reacts when the selected file already exists,
  4427. // and saving would overwrite it. A true value requests a confirmation dialog
  4428. // be presented to the user. A false value requests that the overwrite take
  4429. // place without confirmation. Default value is true.
  4430. //
  4431. // - [Defaultextension] extension
  4432. //
  4433. // Specifies a string that will be appended to the filename if the user enters
  4434. // a filename without an extension. The default value is the empty string,
  4435. // which means no extension will be appended to the filename in any case. This
  4436. // option is ignored on Mac OS X, which does not require extensions to
  4437. // filenames, and the UNIX implementation guesses reasonable values for this
  4438. // from the -filetypes option when this is not supplied.
  4439. //
  4440. // - [Filetypes] filePatternList ([][FileType])
  4441. //
  4442. // If a File types listbox exists in the file dialog on the particular
  4443. // platform, this option gives the filetypes in this listbox. When the user
  4444. // choose a filetype in the listbox, only the files of that type are listed. If
  4445. // this option is unspecified, or if it is set to the empty list, or if the
  4446. // File types listbox is not supported by the particular platform then all
  4447. // files are listed regardless of their types. See the section SPECIFYING FILE
  4448. // PATTERNS below for a discussion on the contents of filePatternList.
  4449. //
  4450. // - [Initialdir] directory
  4451. //
  4452. // Specifies that the files in directory should be displayed when the dialog
  4453. // pops up. If this parameter is not specified, the initial directory defaults
  4454. // to the current working directory on non-Windows systems and on Windows
  4455. // systems prior to Vista. On Vista and later systems, the initial directory
  4456. // defaults to the last user-selected directory for the application. If the
  4457. // parameter specifies a relative path, the return value will convert the
  4458. // relative path to an absolute path.
  4459. //
  4460. // - [Initialfile] filename
  4461. //
  4462. // Specifies a filename to be displayed in the dialog when it pops up.
  4463. //
  4464. // - [Parent] window
  4465. //
  4466. // Makes window the logical parent of the file dialog. The file dialog is
  4467. // displayed on top of its parent window. On Mac OS X, this turns the file
  4468. // dialog into a sheet attached to the parent window.
  4469. //
  4470. // - [Title] titleString
  4471. //
  4472. // Specifies a string to display as the title of the dialog box. If this option
  4473. // is not specified, then a default title is displayed.
  4474. //
  4475. // Additional information might be available at the [Tcl/Tk getopenfile] page.
  4476. //
  4477. // [Tcl/Tk getopenfile]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/getOpenFile.html
  4478. func GetSaveFile(options ...Opt) string {
  4479. return evalErr(fmt.Sprintf("tk_getSaveFile %s", collect(options...)))
  4480. }
  4481. // Place — Geometry manager for fixed or rubber-sheet placement
  4482. //
  4483. // # Description
  4484. //
  4485. // The placer is a geometry manager for Tk. It provides simple fixed placement
  4486. // of windows, where you specify the exact size and location of one window,
  4487. // called the content, within another window, called the container. The placer
  4488. // also provides rubber-sheet placement, where you specify the size and
  4489. // location of the content in terms of the dimensions of the container, so that
  4490. // the content changes size and location in response to changes in the size of
  4491. // the container. Lastly, the placer allows you to mix these styles of
  4492. // placement so that, for example, the content has a fixed width and height but
  4493. // is centered inside the container.
  4494. //
  4495. // The first argument must be a *Window.
  4496. //
  4497. // The following options are supported:
  4498. //
  4499. // - [Anchor] where
  4500. //
  4501. // Where specifies which point of window is to be positioned at the (x,y)
  4502. // location selected by the -x, -y, -relx, and -rely options. The anchor point
  4503. // is in terms of the outer area of window including its border, if any. Thus
  4504. // if where is se then the lower-right corner of window's border will appear at
  4505. // the given (x,y) location in the container. The anchor position defaults to
  4506. // nw.
  4507. //
  4508. // - [Bordermode] mode
  4509. //
  4510. // Mode determines the degree to which borders within the container are used in
  4511. // determining the placement of the content. The default and most common value
  4512. // is inside. In this case the placer considers the area of the container to be
  4513. // the innermost area of the container, inside any border: an option of -x 0
  4514. // corresponds to an x-coordinate just inside the border and an option of
  4515. // -relwidth 1.0 means window will fill the area inside the container's border.
  4516. //
  4517. // If mode is outside then the placer considers the area of the container to
  4518. // include its border; this mode is typically used when placing window outside
  4519. // its container, as with the options -x 0 -y 0 -anchor ne. Lastly, mode may be
  4520. // specified as ignore, in which case borders are ignored: the area of the
  4521. // container is considered to be its official X area, which includes any
  4522. // internal border but no external border. A bordermode of ignore is probably
  4523. // not very useful.
  4524. //
  4525. // - [Height] size
  4526. //
  4527. // Size specifies the height for window in screen units (i.e. any of the forms
  4528. // accepted by Tk_GetPixels). The height will be the outer dimension of window
  4529. // including its border, if any. If size is an empty string, or if no -height
  4530. // or -relheight option is specified, then the height requested internally by
  4531. // the window will be used.
  4532. //
  4533. // - [In] container
  4534. //
  4535. // Container specifies the path name of the window relative to which window is
  4536. // to be placed. Container must either be window's parent or a descendant of
  4537. // window's parent. In addition, container and window must both be descendants
  4538. // of the same top-level window. These restrictions are necessary to guarantee
  4539. // that window is visible whenever container is visible. If this option is not
  4540. // specified then the other window defaults to window's parent.
  4541. //
  4542. // - [Relheight] size
  4543. //
  4544. // Size specifies the height for window. In this case the height is specified
  4545. // as a floating-point number relative to the height of the container: 0.5
  4546. // means window will be half as high as the container, 1.0 means window will
  4547. // have the same height as the container, and so on. If both -height and
  4548. // -relheight are specified for a content, their values are summed. For
  4549. // example, -relheight 1.0 -height -2 makes the content 2 pixels shorter than
  4550. // the container.
  4551. //
  4552. // - [Relwidth] size
  4553. //
  4554. // Size specifies the width for window. In this case the width is specified as
  4555. // a floating-point number relative to the width of the container: 0.5 means
  4556. // window will be half as wide as the container, 1.0 means window will have the
  4557. // same width as the container, and so on. If both -width and -relwidth are
  4558. // specified for a content, their values are summed. For example, -relwidth 1.0
  4559. // -width 5 makes the content 5 pixels wider than the container.
  4560. //
  4561. // - [Relx] location
  4562. //
  4563. // Location specifies the x-coordinate within the container window of the
  4564. // anchor point for window. In this case the location is specified in a
  4565. // relative fashion as a floating-point number: 0.0 corresponds to the left
  4566. // edge of the container and 1.0 corresponds to the right edge of the
  4567. // container. Location need not be in the range 0.0-1.0. If both -x and -relx
  4568. // are specified for a content then their values are summed. For example, -relx
  4569. // 0.5 -x -2 positions the left edge of the content 2 pixels to the left of the
  4570. // center of its container.
  4571. //
  4572. // - [Rely] location
  4573. //
  4574. // Location specifies the y-coordinate within the container window of the
  4575. // anchor point for window. In this case the value is specified in a relative
  4576. // fashion as a floating-point number: 0.0 corresponds to the top edge of the
  4577. // container and 1.0 corresponds to the bottom edge of the container. Location
  4578. // need not be in the range 0.0-1.0. If both -y and -rely are specified for a
  4579. // content then their values are summed. For example, -rely 0.5 -x 3 positions
  4580. // the top edge of the content 3 pixels below the center of its container.
  4581. //
  4582. // - [Width] size
  4583. //
  4584. // Size specifies the width for window in screen units (i.e. any of the forms
  4585. // accepted by Tk_GetPixels). The width will be the outer width of window
  4586. // including its border, if any. If size is an empty string, or if no -width or
  4587. // -relwidth option is specified, then the width requested internally by the
  4588. // window will be used.
  4589. //
  4590. // - [X] location
  4591. //
  4592. // Location specifies the x-coordinate within the container window of the
  4593. // anchor point for window. The location is specified in screen units (i.e. any
  4594. // of the forms accepted by Tk_GetPixels) and need not lie within the bounds of
  4595. // the container window.
  4596. //
  4597. // - [Y] location
  4598. //
  4599. // Location specifies the y-coordinate within the container window of the
  4600. // anchor point for window. The location is specified in screen units (i.e. any
  4601. // of the forms accepted by Tk_GetPixels) and need not lie within the bounds of
  4602. // the container window.
  4603. //
  4604. // If the same value is specified separately with two different options, such
  4605. // as -x and -relx, then the most recent option is used and the older one is
  4606. // ignored.
  4607. //
  4608. // Additional information might be available at the [Tcl/Tk place] page.
  4609. //
  4610. // [Tcl/Tk place]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/place.htm
  4611. func Place(options ...Opt) {
  4612. autocenterDisabled = true
  4613. evalErr(fmt.Sprintf("place %s", collect(options...)))
  4614. }
  4615. // Lower — Change a window's position in the stacking order
  4616. //
  4617. // # Description
  4618. //
  4619. // If the belowThis argument is nil then the command lowers window so that
  4620. // it is below all of its siblings in the stacking order (it will be obscured
  4621. // by any siblings that overlap it and will not obscure any siblings). If
  4622. // belowThis is specified then it must be the path name of a window that is
  4623. // either a sibling of window or the descendant of a sibling of window. In this
  4624. // case the lower command will insert window into the stacking order just below
  4625. // belowThis (or the ancestor of belowThis that is a sibling of window); this
  4626. // could end up either raising or lowering window.
  4627. //
  4628. // All toplevel windows may be restacked with respect to each other, whatever
  4629. // their relative path names, but the window manager is not obligated to
  4630. // strictly honor requests to restack.
  4631. //
  4632. // Additional information might be available at the [Tcl/Tk lower] page.
  4633. //
  4634. // [Tcl/Tk lower]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/lower.html
  4635. func (w *Window) Lower(belowThis Widget) {
  4636. b := ""
  4637. if belowThis != nil {
  4638. b = belowThis.optionString(nil)
  4639. }
  4640. evalErr(fmt.Sprintf("lower %s %s", w, b))
  4641. }
  4642. // Raise — Change a window's position in the stacking order
  4643. //
  4644. // # Description
  4645. //
  4646. // If the aboveThis argument is nil then the command raises window so that it
  4647. // is above all of its siblings in the stacking order (it will not be obscured
  4648. // by any siblings and will obscure any siblings that overlap it). If aboveThis
  4649. // is specified then it must be the path name of a window that is either a
  4650. // sibling of window or the descendant of a sibling of window. In this case the
  4651. // raise command will insert window into the stacking order just above
  4652. // aboveThis (or the ancestor of aboveThis that is a sibling of window); this
  4653. // could end up either raising or lowering window.
  4654. //
  4655. // All toplevel windows may be restacked with respect to each other, whatever
  4656. // their relative path names, but the window manager is not obligated to
  4657. // strictly honor requests to restack.
  4658. //
  4659. // On macOS raising an iconified toplevel window causes it to be deiconified.
  4660. //
  4661. // Additional information might be available at the [Tcl/Tk raise] page.
  4662. //
  4663. // [Tcl/Tk raise]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/raise.html
  4664. func (w *Window) Raise(aboveThis Widget) {
  4665. b := ""
  4666. if aboveThis != nil {
  4667. b = aboveThis.optionString(nil)
  4668. }
  4669. evalErr(fmt.Sprintf("raise %s %s", w, b))
  4670. }
  4671. // MenuItem represents an entry on a menu.
  4672. type MenuItem struct {
  4673. id string
  4674. }
  4675. // String implements fmt.Stringer.
  4676. func (m *MenuItem) String() string {
  4677. return m.optionString(nil)
  4678. }
  4679. func (m *MenuItem) optionString(_ *Window) string {
  4680. if m != nil {
  4681. return m.id
  4682. }
  4683. return "mnu_non_existing"
  4684. }
  4685. // tk_popup — Post a popup menu
  4686. //
  4687. // # Description
  4688. //
  4689. // This procedure posts a menu at a given position on the screen and configures
  4690. // Tk so that the menu and its cascaded children can be traversed with the
  4691. // mouse or the keyboard. Menu is the name of a menu widget and x and y are the
  4692. // root coordinates at which to display the menu. If entry is omitted or an
  4693. // empty string, the menu's upper left corner is positioned at the given point.
  4694. // Otherwise entry gives the index of an entry in menu and the menu will be
  4695. // positioned so that the entry is positioned over the given point.
  4696. //
  4697. // Additional information might be available at the [Tcl/Tk popup] page.
  4698. //
  4699. // [Tcl/Tk popup]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/popup.html
  4700. func Popup(menu *Window, x, y int, entry any) {
  4701. var s string
  4702. if entry != nil && entry != "" {
  4703. s = collectAny(entry)
  4704. }
  4705. evalErr(fmt.Sprintf("tk_popup %s %v %v %s", menu, x, y, s))
  4706. }
  4707. // Menu — Create and manipulate 'menu' widgets and menubars
  4708. //
  4709. // # Description
  4710. //
  4711. // Add a new radiobutton entry to the bottom of the menu.
  4712. //
  4713. // Additional information might be available at the [Tcl/Tk menu] page.
  4714. //
  4715. // [Tcl/Tk menu]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/menu.html
  4716. func (w *MenuWidget) AddRadiobutton(options ...Opt) *MenuItem {
  4717. return &MenuItem{id: evalErr(fmt.Sprintf("%s add radiobutton %s", w, winCollect(w.Window, options...)))}
  4718. }
  4719. // Menu — Create and manipulate 'menu' widgets and menubars
  4720. //
  4721. // # Description
  4722. //
  4723. // Add a new checkbutton entry to the bottom of the menu.
  4724. //
  4725. // Additional information might be available at the [Tcl/Tk menu] page.
  4726. //
  4727. // [Tcl/Tk menu]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/menu.html
  4728. func (w *MenuWidget) AddCheckbutton(options ...Opt) *MenuItem {
  4729. return &MenuItem{id: evalErr(fmt.Sprintf("%s add checkbutton %s", w, winCollect(w.Window, options...)))}
  4730. }
  4731. // Menu — Create and manipulate 'menu' widgets and menubars
  4732. //
  4733. // # Description
  4734. //
  4735. // Add a new command entry to the bottom of the menu.
  4736. //
  4737. // Additional information might be available at the [Tcl/Tk menu] page.
  4738. //
  4739. // [Tcl/Tk menu]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/menu.html
  4740. func (w *MenuWidget) AddCommand(options ...Opt) *MenuItem {
  4741. return &MenuItem{id: evalErr(fmt.Sprintf("%s add command %s", w, winCollect(w.Window, options...)))}
  4742. }
  4743. // Menu — Create and manipulate 'menu' widgets and menubars
  4744. //
  4745. // # Description
  4746. //
  4747. // Add a new cascade entry to the end of the menu.
  4748. //
  4749. // Additional information might be available at the [Tcl/Tk menu] page.
  4750. //
  4751. // [Tcl/Tk menu]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/menu.html
  4752. func (w *MenuWidget) AddCascade(options ...Opt) *MenuItem {
  4753. return &MenuItem{id: evalErr(fmt.Sprintf("%s add cascade %s", w, winCollect(w.Window, options...)))}
  4754. }
  4755. // Menu — Create and manipulate 'menu' widgets and menubars
  4756. //
  4757. // # Description
  4758. //
  4759. // Add a new separator entry to the bottom of the menu.
  4760. //
  4761. // Additional information might be available at the [Tcl/Tk menu] page.
  4762. //
  4763. // [Tcl/Tk menu]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/menu.html
  4764. func (w *MenuWidget) AddSeparator(options ...Opt) *MenuItem {
  4765. return &MenuItem{id: evalErr(fmt.Sprintf("%s add separator %s", w, winCollect(w.Window, options...)))}
  4766. }
  4767. // Menu — Create and manipulate 'menu' widgets and menubars
  4768. //
  4769. // # Description
  4770. //
  4771. // Invoke the action of the menu entry. See the sections on the individual
  4772. // entries above for details on what happens. If the menu entry is disabled
  4773. // then nothing happens. If the entry has a command associated with it then the
  4774. // result of that command is returned as the result of the invoke widget
  4775. // command. Otherwise the result is an empty string. Note: invoking a menu
  4776. // entry does not automatically unpost the menu; the default bindings normally
  4777. // take care of this before invoking the invoke widget command.
  4778. //
  4779. // Additional information might be available at the [Tcl/Tk menu] page.
  4780. //
  4781. // [Tcl/Tk menu]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/menu.html
  4782. func (w *MenuWidget) Invoke(index uint) {
  4783. evalErr(fmt.Sprintf("%s invoke %d", w, index))
  4784. }
  4785. // Menu — Create and manipulate 'menu' widgets and menubars
  4786. //
  4787. // # Description
  4788. //
  4789. // This command is similar to the configure command, except that it applies to
  4790. // the options for an individual entry, whereas configure applies to the
  4791. // options for the menu as a whole. Options may have any of the values
  4792. // described in the MENU ENTRY OPTIONS section below. If options are specified,
  4793. // options are modified as indicated in the command and the command returns an
  4794. // empty string. If no options are specified, returns a list describing the
  4795. // current options for entry index (see Tk_ConfigureInfo for information on the
  4796. // format of this list).
  4797. //
  4798. // Additional information might be available at the [Tcl/Tk menu] page.
  4799. //
  4800. // [Tcl/Tk menu]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/menu.html
  4801. func (w *MenuWidget) EntryConfigure(index any, options ...Opt) {
  4802. index = tclSafeString(fmt.Sprint(index))
  4803. options, tvs, vs := w.split(options)
  4804. if len(options) != 0 {
  4805. evalErr(fmt.Sprintf("%s entryconfigure %s %s", w, index, collect(options...)))
  4806. }
  4807. if len(tvs) != 0 {
  4808. tvo := tvs[len(tvs)-1]
  4809. tclVar := textVariables[w.Window]
  4810. if tclVar == "" {
  4811. tclVar = fmt.Sprintf("textVar%d", id.Add(1))
  4812. textVariables[w.Window] = tclVar
  4813. evalErr(fmt.Sprintf("%s entryconfigure %s -textvariable %s", w, index, tclVar))
  4814. }
  4815. evalErr(fmt.Sprintf("set %s %s", tclVar, tclSafeString(string(tvo))))
  4816. }
  4817. if len(vs) != 0 {
  4818. vo := vs[len(vs)-1]
  4819. variables[w.Window] = vo
  4820. if vo.tclName == "" {
  4821. vo.tclName = fmt.Sprintf("goVar%d", id.Add(1))
  4822. }
  4823. evalErr(fmt.Sprintf("%s entryconfigure %s -variable %s", w, index, vo.tclName))
  4824. evalErr(fmt.Sprintf("set %s %s", vo.tclName, tclSafeString(fmt.Sprint(vo.val))))
  4825. }
  4826. }
  4827. // Menu — Create and manipulate 'menu' widgets and menubars
  4828. //
  4829. // # Description
  4830. //
  4831. // Returns the current value of a configuration option for the entry given by
  4832. // index. Option may have any of the names described in the MENU ENTRY OPTIONS
  4833. // section below.
  4834. //
  4835. // Additional information might be available at the [Tcl/Tk menu] page.
  4836. //
  4837. // [Tcl/Tk menu]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/menu.html
  4838. func (w *MenuWidget) EntryCget(index, option any) (r string) {
  4839. return evalErr(fmt.Sprintf("%s entrycget %s %s", w, tclSafeString(fmt.Sprint(index)), funcToTclOption(option)))
  4840. }
  4841. // Menu — Create and manipulate 'menu' widgets and menubars
  4842. //
  4843. // # Description
  4844. //
  4845. // Returns the id of the menu entry given by index. This is the identifier that was
  4846. // assigned to the entry when it was created using the add or insert widget command.
  4847. // Returns an empty string for the tear-off entry, or if index is equivalent to {}.
  4848. //
  4849. // Note that while the raw tk command returns an id, that alone is of no practical use
  4850. // to the caller. So a MenuItem representing the id is returned.
  4851. //
  4852. // Additional information might be available at the [Tcl/Tk menu] page.
  4853. //
  4854. // [Tcl/Tk menu]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/menu.html
  4855. func (m *MenuWidget) Id(index int) *MenuItem {
  4856. id := evalErr(fmt.Sprintf("%s id %d", m, index))
  4857. return &MenuItem{id: id}
  4858. }
  4859. // Menu — Create and manipulate 'menu' widgets and menubars
  4860. //
  4861. // # Description
  4862. //
  4863. // Returns the numerical index corresponding to a MenuItem.
  4864. //
  4865. // Additional information might be available at the [Tcl/Tk menu] page.
  4866. //
  4867. // [Tcl/Tk menu]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/menu.html
  4868. func (m *MenuWidget) Index(item *MenuItem) int {
  4869. index := evalErr(fmt.Sprintf("%s index %s", m, item.id))
  4870. return atoi(index)
  4871. }
  4872. // TScrollbar — Control the viewport of a scrollable widget
  4873. //
  4874. // # Description
  4875. //
  4876. // This command is normally invoked by the scrollbar's associated widget from
  4877. // an -xscrollcommand or -yscrollcommand callback. Specifies the visible range
  4878. // to be displayed. first and last are real fractions between 0 and 1.
  4879. //
  4880. // More information might be available at the [Tcl/Tk ttk_scrollbar] page.
  4881. //
  4882. // [Tcl/Tk ttk_scrollbar]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_scrollbar.html
  4883. func (w *TScrollbarWidget) Set(firstLast string) {
  4884. evalErr(fmt.Sprintf("%s set %s", w, firstLast))
  4885. }
  4886. // tk — Manipulate Tk internal state
  4887. //
  4888. // # Description
  4889. //
  4890. // Sets and queries the current scaling factor used by Tk to convert between
  4891. // physical units (for example, points, inches, or millimeters) and pixels. The
  4892. // number argument is a floating point number that specifies the number of
  4893. // pixels per point on window's display. If the window argument is omitted, it
  4894. // defaults to the main window. If the number argument is omitted, the current
  4895. // value of the scaling factor is returned.
  4896. //
  4897. // A “point” is a unit of measurement equal to 1/72 inch. A scaling factor of
  4898. // 1.0 corresponds to 1 pixel per point, which is equivalent to a standard 72
  4899. // dpi monitor. A scaling factor of 1.25 would mean 1.25 pixels per point,
  4900. // which is the setting for a 90 dpi monitor; setting the scaling factor to
  4901. // 1.25 on a 72 dpi monitor would cause everything in the application to be
  4902. // displayed 1.25 times as large as normal. The initial value for the scaling
  4903. // factor is set when the application starts, based on properties of the
  4904. // installed monitor, but it can be changed at any time. Measurements made
  4905. // after the scaling factor is changed will use the new scaling factor, but it
  4906. // is undefined whether existing widgets will resize themselves dynamically to
  4907. // accommodate the new scaling factor.
  4908. //
  4909. // - [Displayof] window
  4910. //
  4911. // - Number
  4912. //
  4913. // Additional information might be available at the [Tcl/Tk tk] page.
  4914. //
  4915. // [Tcl/Tk tk]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/tk.html
  4916. func TkScaling(options ...any) float64 {
  4917. var a []Opt
  4918. for _, v := range options {
  4919. switch x := v.(type) {
  4920. case Opts:
  4921. a = append(a, x)
  4922. case Opt:
  4923. a = append(a, x)
  4924. default:
  4925. a = append(a, stringOption(fmt.Sprint(x)))
  4926. }
  4927. }
  4928. if s := evalErr(fmt.Sprintf("tk scaling %s", collect(a...))); s != "" {
  4929. n, err := strconv.ParseFloat(s, 64)
  4930. if err == nil {
  4931. return n
  4932. }
  4933. fail(err)
  4934. }
  4935. return 1
  4936. }
  4937. // Font option.
  4938. //
  4939. // Specifies the font to use when drawing text inside the widget.
  4940. // The value may have any of the forms described in the font manual
  4941. // page under FONT DESCRIPTION.
  4942. //
  4943. // Known uses:
  4944. // - [Button]
  4945. // - [Checkbutton]
  4946. // - [Entry]
  4947. // - [Fontchooser] (command specific)
  4948. // - [Label]
  4949. // - [Labelframe]
  4950. // - [Listbox]
  4951. // - [MenuWidget.AddCascade] (command specific)
  4952. // - [MenuWidget.AddCommand] (command specific)
  4953. // - [MenuWidget.AddSeparator] (command specific)
  4954. // - [Menu]
  4955. // - [Menubutton]
  4956. // - [Message]
  4957. // - [Radiobutton]
  4958. // - [Scale]
  4959. // - [Spinbox]
  4960. // - [TEntry]
  4961. // - [TLabel]
  4962. // - [TProgressbar]
  4963. // - [TextWidget.TagConfigure] (command specific)
  4964. // - [Text]
  4965. func Font(list ...any) Opt {
  4966. return rawOption(fmt.Sprintf(`-font {%s}`, tclSafeList(list...)))
  4967. }
  4968. // Font — Get the configured option value.
  4969. //
  4970. // Known uses:
  4971. // - [Button]
  4972. // - [Checkbutton]
  4973. // - [Entry]
  4974. // - [Label]
  4975. // - [Labelframe]
  4976. // - [Listbox]
  4977. // - [Menu]
  4978. // - [Menubutton]
  4979. // - [Message]
  4980. // - [Radiobutton]
  4981. // - [Scale]
  4982. // - [Spinbox]
  4983. // - [TEntry]
  4984. // - [TLabel]
  4985. // - [TProgressbar]
  4986. // - [Text]
  4987. func (w *Window) Font() string {
  4988. return evalErr(fmt.Sprintf(`%s cget -font`, w))
  4989. }
  4990. // + ttk::style configure style ?-option ?value option value...? ?
  4991. // + ttk::style element args
  4992. // + ttk::style element create elementName type ?args...?
  4993. // + ttk::style element names
  4994. // + ttk::style element options element
  4995. // + ttk::style layout style ?layoutSpec?
  4996. // + ttk::style lookup style -option ?state ?default??
  4997. // + ttk::style map style ?-option { statespec value... }?
  4998. // - ttk::style theme args
  4999. // - ttk::style theme create themeName ?-parent basedon? ?-settings script... ?
  5000. // + ttk::style theme names
  5001. // - ttk::style theme settings themeName script
  5002. // + ttk::style theme styles ?themeName?
  5003. // + ttk::style theme use ?themeName?
  5004. // ttk::style — Manipulate style database
  5005. //
  5006. // # Description
  5007. //
  5008. // Sets the default value of the specified option(s) in style. If style does
  5009. // not exist, it is created. Example:
  5010. //
  5011. // StyleConfigure(".", Font("times"), Background(LightBlue))
  5012. //
  5013. // If only style and -option are specified, get the default value for option
  5014. // -option of style style. Example:
  5015. //
  5016. // StyleConfigure(".", Font)
  5017. //
  5018. // If only style is specified, get the default value for all options of style
  5019. // style. Example:
  5020. //
  5021. // StyleConfigure(".")
  5022. //
  5023. // Additional information might be available at the [Tcl/Tk style] page.
  5024. // There's also a [Styles and Themes] tutorial at tkdoc.com.
  5025. //
  5026. // [Tcl/Tk style]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_style.html
  5027. // [Styles and Themes]: https://tkdocs.com/tutorial/styles.html
  5028. func StyleConfigure(style string, options ...any) []string {
  5029. if len(options) == 0 {
  5030. return parseList(evalErr(fmt.Sprintf("ttk::style configure %s", tclSafeString(style))))
  5031. }
  5032. if len(options) == 1 {
  5033. o := options[0]
  5034. if x, ok := o.(Opt); ok {
  5035. return []string{evalErr(fmt.Sprintf("ttk::style configure %s %s", tclSafeString(style), x.optionString(nil)))}
  5036. }
  5037. if s := funcToTclOption(o); s != "" {
  5038. return []string{evalErr(fmt.Sprintf("ttk::style configure %s %s", tclSafeString(style), s))}
  5039. }
  5040. return nil
  5041. }
  5042. var a []string
  5043. for _, v := range options {
  5044. switch x := v.(type) {
  5045. case Opt:
  5046. a = append(a, x.optionString(nil))
  5047. default:
  5048. fail(fmt.Errorf("expected Opt: %T", x))
  5049. return nil
  5050. }
  5051. }
  5052. return []string{evalErr(fmt.Sprintf("ttk::style configure %s %s", tclSafeString(style), strings.Join(a, " ")))}
  5053. }
  5054. func funcToTclOption(fn any) string {
  5055. t := reflect.TypeOf(fn)
  5056. if t.Kind() != reflect.Func {
  5057. return ""
  5058. }
  5059. s := runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name()
  5060. if s == "" {
  5061. fail(fmt.Errorf("failed to determine function name"))
  5062. return ""
  5063. }
  5064. a := strings.Split(s, ".")
  5065. if len(a) == 0 {
  5066. fail(fmt.Errorf("failed to determine function name: %q", s))
  5067. return ""
  5068. }
  5069. s = strings.ToLower(a[len(a)-1])
  5070. if r, ok := replaceOpt[s]; ok {
  5071. return "-" + r
  5072. }
  5073. return "-" + s
  5074. }
  5075. var replaceOpt = map[string]string{
  5076. "btn": "button",
  5077. "lbl": "label",
  5078. "mnu": "menu",
  5079. "msg": "message",
  5080. "txt": "text",
  5081. }
  5082. // ttk::style — Manipulate style database
  5083. //
  5084. // # Description
  5085. //
  5086. // Creates a new element in the current theme of type type. The only
  5087. // cross-platform built-in element type is image (see ttk_image(n)) but themes
  5088. // may define other element types (see Ttk_RegisterElementFactory). On suitable
  5089. // versions of Windows an element factory is registered to create Windows theme
  5090. // elements (see ttk_vsapi(n)). Examples:
  5091. //
  5092. // StyleElementCreate("TSpinbox.uparrow", "from", "default") // Inherit the existing element from theme 'default'.
  5093. //
  5094. // StyleElementCreate("Red.Corner.TButton.indicator", "image", NewPhoto(File("red_corner.png")), Width(10))
  5095. //
  5096. // imageN := NewPhoto(...)
  5097. // StyleElementCreate("TCheckbutton.indicator", "image", image5, "disabled selected", image6, "disabled alternate",
  5098. // image8, "disabled", image9, "alternate", image7, "!selected", image4, Width(20), Border(4), Sticky("w"))
  5099. //
  5100. // After the type "image" comes a list of one or more images. Every image is
  5101. // optionally followed by a space separated list of states the image applies
  5102. // to. An exclamation mark before the state is a negation.
  5103. //
  5104. // Additional information might be available at the [Tcl/Tk modifying a button]
  5105. // and [Tcl/Tk style] pages.
  5106. // There's also a [Styles and Themes] tutorial at tkdoc.com.
  5107. //
  5108. // [Tcl/Tk style]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_style.html
  5109. // [Tcl/Tk modifying a button]: https://wiki.tcl-lang.org/page/Tutorial%3A+Modifying+a+ttk+button%27s+style
  5110. // [Styles and Themes]: https://tkdocs.com/tutorial/styles.html
  5111. func StyleElementCreate(elementName, typ string, options ...any) string {
  5112. // ttk::style element create TRadiobutton.indicator image {pyimage11 {disabled selected} pyimage12 disabled pyimage13 !selected pyimage10} -width 20 -border 4 -sticky w
  5113. var a, b []string
  5114. for _, v := range options {
  5115. switch x := v.(type) {
  5116. case *Img:
  5117. a = append(a, x.optionString(nil))
  5118. case Opt:
  5119. b = append(b, x.optionString(nil))
  5120. default:
  5121. switch s := strings.Fields(fmt.Sprint(v)); {
  5122. case len(s) == 1:
  5123. a = append(a, tclSafeInBraces(s[0]))
  5124. default:
  5125. for i, v := range s {
  5126. s[i] = tclSafeInBraces(v)
  5127. }
  5128. a = append(a, fmt.Sprintf("{%s}", strings.Join(s, " ")))
  5129. }
  5130. }
  5131. }
  5132. switch {
  5133. case len(a) == 2 && a[0] == "from":
  5134. return evalErr(fmt.Sprintf("ttk::style element create from %s", a[1]))
  5135. default:
  5136. return evalErr(fmt.Sprintf("ttk::style element create {%s} image {%s} %s", tclSafeInBraces(elementName), strings.Join(a, " "), strings.Join(b, " ")))
  5137. }
  5138. }
  5139. // ttk::style — Manipulate style database
  5140. //
  5141. // # Description
  5142. //
  5143. // Returns the list of elements defined in the current theme.
  5144. //
  5145. // Additional information might be available at the [Tcl/Tk style] page.
  5146. // There's also a [Styles and Themes] tutorial at tkdoc.com.
  5147. //
  5148. // [Tcl/Tk style]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_style.html
  5149. // [Styles and Themes]: https://tkdocs.com/tutorial/styles.html
  5150. func StyleElementNames() []string {
  5151. return parseList(evalErr("ttk::style element names"))
  5152. }
  5153. // ttk::style — Manipulate style database
  5154. //
  5155. // # Description
  5156. //
  5157. // Returns the list of element's options.
  5158. //
  5159. // Additional information might be available at the [Tcl/Tk style] page.
  5160. // There's also a [Styles and Themes] tutorial at tkdoc.com.
  5161. //
  5162. // [Tcl/Tk style]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_style.html
  5163. // [Styles and Themes]: https://tkdocs.com/tutorial/styles.html
  5164. func StyleElementOptions(element string) []string {
  5165. return parseList(evalErr(fmt.Sprintf("ttk::style element options %s", tclSafeString(element))))
  5166. }
  5167. // ttk::style — Manipulate style database
  5168. //
  5169. // # Description
  5170. //
  5171. // Define the widget layout for style style. See LAYOUTS below for the format
  5172. // of layoutSpec. If layoutSpec is omitted, return the layout specification for
  5173. // style style. Example:
  5174. //
  5175. // StyleLayout("Red.Corner.Button",
  5176. // "Button.border", Sticky("nswe"), Border(1), Children(
  5177. // "Button.focus", Sticky("nswe"), Children(
  5178. // "Button.padding", Sticky("nswe"), Children(
  5179. // "Button.label", Sticky("nswe"),
  5180. // "Red.Corner.TButton.indicator", Side("right"), Sticky("ne")))))
  5181. //
  5182. // Additional information might be available at the [Tcl/Tk modifying a button]
  5183. // and [Tcl/Tk style] pages.
  5184. // There's also a [Styles and Themes] tutorial at tkdoc.com.
  5185. //
  5186. // [Tcl/Tk style]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_style.html
  5187. // [Tcl/Tk modifying a button]: https://wiki.tcl-lang.org/page/Tutorial%3A+Modifying+a+ttk+button%27s+style
  5188. // [Styles and Themes]: https://tkdocs.com/tutorial/styles.html
  5189. func StyleLayout(style string, options ...any) string {
  5190. if len(options) == 0 {
  5191. return evalErr(fmt.Sprintf("ttk::style layout %s", tclSafeString(style)))
  5192. }
  5193. evalErr(fmt.Sprintf("ttk::style layout %s %s", tclSafeString(style), children("", options...)))
  5194. return ""
  5195. }
  5196. // ttk::style — Manipulate style database
  5197. //
  5198. // # Description
  5199. //
  5200. // Returns the value specified for -option in style style in state state, using
  5201. // the standard lookup rules for element options. state is a list of state
  5202. // names; if omitted, it defaults to all bits off (the “normal” state). If the
  5203. // default argument is present, it is used as a fallback value in case no
  5204. // specification for -option is found. If style does not exist, it is created.
  5205. // For example,
  5206. //
  5207. // StyleLookup("TButton", Font)
  5208. //
  5209. // may return "TkDefaultFont", depending on the operating system, theme in use
  5210. // and the configured style options.
  5211. //
  5212. // Additional information might be available at the [Tcl/Tk style] page.
  5213. // There's also a [Styles and Themes] tutorial at tkdoc.com.
  5214. //
  5215. // [Tcl/Tk style]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_style.html
  5216. // [Styles and Themes]: https://tkdocs.com/tutorial/styles.html
  5217. func StyleLookup(style string, options ...any) string {
  5218. for i, v := range options {
  5219. if s := funcToTclOption(v); s != "" {
  5220. options[i] = rawOption(s)
  5221. }
  5222. }
  5223. return evalErr(fmt.Sprintf("ttk::style lookup %s %s", tclSafeString(style), collectAny(options...)))
  5224. }
  5225. // ttk::style — Manipulate style database
  5226. //
  5227. // # Description
  5228. //
  5229. // Sets dynamic (state dependent) values of the specified option(s) in style.
  5230. // Each statespec / value pair is examined in order; the value corresponding to
  5231. // the first matching statespec is used. If style does not exist, it is
  5232. // created. If only style and -option are specified, get the dynamic values for
  5233. // option -option of style style. If only style is specified, get the dynamic
  5234. // values for all options of style 'style'.
  5235. //
  5236. // With no options the function returns the currently configured style map for
  5237. // 'style'. For example,
  5238. //
  5239. // StyleMap("TButton")
  5240. //
  5241. // may return "-relief {{!disabled pressed} sunken}", depending on the
  5242. // operating system, theme in use and the configured style options.
  5243. //
  5244. // Setting a style map is done by providing a list of options, each option is
  5245. // followed by a list of states and a value. For example:
  5246. //
  5247. // StyleMap("TButton",
  5248. // Background, "disabled", "#112233", "active", "#445566",
  5249. // Foreground, "disabled", "#778899",
  5250. // Relief, "pressed", "!disabled", "sunken")
  5251. //
  5252. // # Widget states
  5253. //
  5254. // The widget state is a bitmap of independent state flags.
  5255. //
  5256. // - active - The mouse cursor is over the widget and pressing a mouse button
  5257. // will cause some action to occur
  5258. // - alternate - A widget-specific alternate display format
  5259. // - background - Windows and Mac have a notion of an “active” or foreground
  5260. // window. The background state is set for widgets in a background window,
  5261. // and cleared for those in the foreground window
  5262. // - disabled - Widget is disabled under program control
  5263. // - focus - Widget has keyboard focus
  5264. // - invalid - The widget’s value is invalid
  5265. // - pressed - Widget is being pressed
  5266. // - readonly - Widget should not allow user modification
  5267. // - selected - “On”, “true”, or “current” for things like Checkbuttons and
  5268. // radiobuttons
  5269. // - hover - The mouse cursor is within the widget. This is similar to the
  5270. // active state; it is used in some themes for widgets that provide distinct
  5271. // visual feedback for the active widget in addition to the active element
  5272. // within the widget.
  5273. // - user1-user6 - Freely usable for other purposes
  5274. //
  5275. // A state specification is a sequence of state names, optionally prefixed with
  5276. // an exclamation point indicating that the bit is off.
  5277. //
  5278. // Additional information might be available at the [Tcl/Tk style] page.
  5279. // There's also a [Styles and Themes] tutorial at tkdoc.com.
  5280. //
  5281. // [Tcl/Tk style]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_style.html
  5282. // [Styles and Themes]: https://tkdocs.com/tutorial/styles.html
  5283. func StyleMap(style string, options ...any) string {
  5284. if len(options) == 0 {
  5285. return evalErr(fmt.Sprintf("ttk::style map %s", tclSafeString(style)))
  5286. }
  5287. a, err := parseStyleMapOpts(options...)
  5288. if err != nil {
  5289. fail(fmt.Errorf("parsing StyleMap options: %v", err))
  5290. return ""
  5291. }
  5292. evalErr(fmt.Sprintf("ttk::style map %s %s", tclSafeString(style), strings.Join(a, " ")))
  5293. return ""
  5294. }
  5295. func parseStyleMapOpts(in ...any) (r []string, err error) {
  5296. for len(in) != 0 {
  5297. opt := funcToTclOption(in[0])
  5298. if opt == "" {
  5299. return nil, fmt.Errorf("expected option, eg. 'Relief' (the function, not Relief(argument)), got %T", in[0])
  5300. }
  5301. in = in[1:]
  5302. r = append(r, opt)
  5303. var list []string
  5304. for {
  5305. var states []string
  5306. for len(in) != 0 {
  5307. s, ok := in[0].(string)
  5308. if !ok || !isState(s) {
  5309. break
  5310. }
  5311. states = append(states, s)
  5312. in = in[1:]
  5313. }
  5314. if len(in) == 0 {
  5315. return nil, fmt.Errorf("missing option value")
  5316. }
  5317. val := tclSafeString(fmt.Sprint(in[0]))
  5318. in = in[1:]
  5319. var s string
  5320. switch len(states) {
  5321. case 0:
  5322. // nop
  5323. case 1:
  5324. s = states[0]
  5325. default:
  5326. s = fmt.Sprintf("{%s}", strings.Join(states, " "))
  5327. }
  5328. list = append(list, fmt.Sprintf("%s %s", s, val))
  5329. if len(in) == 0 || funcToTclOption(in[0]) != "" {
  5330. break
  5331. }
  5332. }
  5333. r = append(r, fmt.Sprintf("{%s}", strings.Join(list, " ")))
  5334. }
  5335. return r, nil
  5336. }
  5337. // https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_widget.html#M34
  5338. func isState(s string) bool {
  5339. if len(s) == 0 {
  5340. return false
  5341. }
  5342. if s[0] == '!' {
  5343. s = s[1:]
  5344. }
  5345. switch s {
  5346. case
  5347. "active",
  5348. "disabled",
  5349. "focus",
  5350. "pressed",
  5351. "selected",
  5352. "background",
  5353. "readonly",
  5354. "alternate",
  5355. "invalid",
  5356. "hover",
  5357. "user1",
  5358. "user2",
  5359. "user3",
  5360. "user4",
  5361. "user5",
  5362. "user6":
  5363. return true
  5364. default:
  5365. return false
  5366. }
  5367. }
  5368. // Border option.
  5369. //
  5370. // Known uses:
  5371. // - [StyleLayout]
  5372. func Border(val any) Opt {
  5373. return rawOption(fmt.Sprintf(`-border %s`, optionString(val)))
  5374. }
  5375. // Focuscolor option.
  5376. //
  5377. // Known uses:
  5378. // - [StyleConfigure]
  5379. func Focuscolor(val any) Opt {
  5380. return rawOption(fmt.Sprintf(`-focuscolor %s`, optionString(val)))
  5381. }
  5382. // Focusthickness option.
  5383. //
  5384. // Known uses:
  5385. // - [StyleConfigure]
  5386. func Focusthickness(val any) Opt {
  5387. return rawOption(fmt.Sprintf(`-focusthickness %s`, optionString(val)))
  5388. }
  5389. // Focussolid option.
  5390. //
  5391. // Known uses:
  5392. // - [StyleConfigure]
  5393. func Focussolid(val any) Opt {
  5394. return rawOption(fmt.Sprintf(`-focussolid %s`, optionString(val)))
  5395. }
  5396. // Children option.
  5397. //
  5398. // Known uses:
  5399. // - [StyleLayout]
  5400. //
  5401. // Children describes children of a style layout.
  5402. func Children(list ...any) Opt {
  5403. return children("-children", list...)
  5404. }
  5405. func children(prefixed string, list ...any) Opt {
  5406. var a []string
  5407. for _, v := range list {
  5408. a = append(a, fmt.Sprint(v))
  5409. }
  5410. return rawOption(fmt.Sprintf(" %s {%s}", prefixed, strings.Join(a, " ")))
  5411. }
  5412. // ttk::style — Manipulate style database
  5413. //
  5414. // # Description
  5415. //
  5416. // Returns a list of all known themes.
  5417. //
  5418. // Additional information might be available at the [Tcl/Tk style] page.
  5419. //
  5420. // [Tcl/Tk style]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_style.html
  5421. func StyleThemeNames() []string {
  5422. return parseList(evalErr("ttk::style theme names"))
  5423. }
  5424. // ttk::style — Manipulate style database
  5425. //
  5426. // # Description
  5427. //
  5428. // Returns a list of all styles in themeName. If themeName is omitted, the
  5429. // current theme is used.
  5430. //
  5431. // Additional information might be available at the [Tcl/Tk style] page.
  5432. //
  5433. // [Tcl/Tk style]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_style.html
  5434. func StyleThemeStyles(themeName ...string) []string {
  5435. var s string
  5436. if len(themeName) != 0 {
  5437. s = tclSafeString(themeName[0])
  5438. }
  5439. return parseList(evalErr(fmt.Sprintf("ttk::style theme styles %s", s)))
  5440. }
  5441. // ttk::style — Manipulate style database
  5442. //
  5443. // # Description
  5444. //
  5445. // Without a argument the result is the name of the current theme. Otherwise
  5446. // this command sets the current theme to themeName, and refreshes all widgets.
  5447. //
  5448. // Additional information might be available at the [Tcl/Tk style] page.
  5449. // There's also a [Styles and Themes] tutorial at tkdoc.com.
  5450. //
  5451. // This mechanism is separate from the RegisterTheme/ActivateTheme one. Use of
  5452. // this function is best suited for the built in themes like "clam" etc.
  5453. //
  5454. // [Tcl/Tk style]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_style.html
  5455. // [Styles and Themes]: https://tkdocs.com/tutorial/styles.html
  5456. func StyleThemeUse(themeName ...string) string {
  5457. var s string
  5458. if len(themeName) != 0 {
  5459. s = tclSafeString(themeName[0])
  5460. }
  5461. return evalErr(fmt.Sprintf("ttk::style theme use %s", s))
  5462. }
  5463. // CourierFont returns "{courier new}" on Windows and "courier" elsewhere.
  5464. func CourierFont() string {
  5465. if goos == "windows" {
  5466. return "courier new"
  5467. }
  5468. return "courier"
  5469. }
  5470. // button — Create and manipulate 'button' action widgets
  5471. //
  5472. // # Description
  5473. //
  5474. // Invoke the Tcl command associated with the button, if there is one. The
  5475. // return value is the return value from the Tcl command, or an empty string if
  5476. // there is no command associated with the button. This command is ignored if
  5477. // the button's state is disabled.
  5478. //
  5479. // Additional information might be available at the [Tcl/Tk button] page.
  5480. //
  5481. // [Tcl/Tk button]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/button.html
  5482. func (w *ButtonWidget) Invoke() string {
  5483. return evalErr(fmt.Sprintf("%s invoke", w))
  5484. }
  5485. // TButton — Widget that issues a command when pressed
  5486. //
  5487. // # Description
  5488. //
  5489. // Invokes the command associated with the button.
  5490. //
  5491. // Additional information might be available at the [Tcl/Tk ttk::button] page.
  5492. //
  5493. // [Tcl/Tk ttk::button]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_button.html
  5494. func (w *TButtonWidget) Invoke() string {
  5495. return evalErr(fmt.Sprintf("%s invoke", w))
  5496. }
  5497. // TButton — Widget that issues a command when pressed
  5498. //
  5499. // # Description
  5500. //
  5501. // Shiftrelief specifies how far the button contents are shifted down and right
  5502. // in the pressed state. This action provides additional skeuomorphic feedback.
  5503. func Shiftrelief(val any) Opt {
  5504. return rawOption(fmt.Sprintf(`-shiftrelief %s`, optionString(val)))
  5505. }
  5506. // Bordercolor — Styling widgets
  5507. //
  5508. // Bordercolor is a styling option of one or more widgets. Please see [Changing
  5509. // Widget Colors] for details.
  5510. //
  5511. // [Changing Widget Colors]: https://wiki.tcl-lang.org/page/Changing+Widget+Colors
  5512. func Bordercolor(val any) Opt {
  5513. return rawOption(fmt.Sprintf(`-bordercolor %s`, optionString(val)))
  5514. }
  5515. // Darkcolor — Styling widgets
  5516. //
  5517. // Darkcolor is a styling option of one or more widgets. Please see [Changing
  5518. // Widget Colors] for details.
  5519. //
  5520. // [Changing Widget Colors]: https://wiki.tcl-lang.org/page/Changing+Widget+Colors
  5521. func Darkcolor(val any) Opt {
  5522. return rawOption(fmt.Sprintf(`-darkcolor %s`, optionString(val)))
  5523. }
  5524. // Lightcolor — Styling widgets
  5525. //
  5526. // Lightcolor is a styling option of one or more widgets. Please see [Changing
  5527. // Widget Colors] for details.
  5528. //
  5529. // [Changing Widget Colors]: https://wiki.tcl-lang.org/page/Changing+Widget+Colors
  5530. func Lightcolor(val any) Opt {
  5531. return rawOption(fmt.Sprintf(`-lightcolor %s`, optionString(val)))
  5532. }
  5533. // Indicatorbackground — Styling widgets
  5534. //
  5535. // Indicatorbackground is a styling option of one or more widgets. Please see
  5536. // [Changing Widget Colors] for details.
  5537. //
  5538. // [Changing Widget Colors]: https://wiki.tcl-lang.org/page/Changing+Widget+Colors
  5539. func Indicatorbackground(val any) Opt {
  5540. return rawOption(fmt.Sprintf(`-indicatorbackground %s`, optionString(val)))
  5541. }
  5542. // Indicatorcolor — Styling widgets
  5543. //
  5544. // Indicatorcolor is a styling option of one or more widgets. Please see
  5545. // [Changing Widget Colors] for details.
  5546. //
  5547. // [Changing Widget Colors]: https://wiki.tcl-lang.org/page/Changing+Widget+Colors
  5548. func Indicatorcolor(val any) Opt {
  5549. return rawOption(fmt.Sprintf(`-indicatorcolor %s`, optionString(val)))
  5550. }
  5551. // Indicatormargin — Styling widgets
  5552. //
  5553. // Indicatormargin is a styling option of one or more widgets. Please see
  5554. // [Changing Widget Colors] for details.
  5555. //
  5556. // [Changing Widget Colors]: https://wiki.tcl-lang.org/page/Changing+Widget+Colors
  5557. func Indicatormargin(val any) Opt {
  5558. return rawOption(fmt.Sprintf(`-indicatormargin %s`, optionString(val)))
  5559. }
  5560. // Indicatorrelief — Styling widgets
  5561. //
  5562. // Indicatorrelief is a styling option of one or more widgets. Please see
  5563. // [Changing Widget Colors] for details.
  5564. //
  5565. // [Changing Widget Colors]: https://wiki.tcl-lang.org/page/Changing+Widget+Colors
  5566. func Indicatorrelief(val any) Opt {
  5567. return rawOption(fmt.Sprintf(`-indicatorrelief %s`, optionString(val)))
  5568. }
  5569. // Arrowcolor — Styling widgets
  5570. //
  5571. // Arrowcolor is a styling option of one or more widgets. Please see
  5572. // [Changing Widget Colors] for details.
  5573. //
  5574. // [Changing Widget Colors]: https://wiki.tcl-lang.org/page/Changing+Widget+Colors
  5575. func Arrowcolor(val any) Opt {
  5576. return rawOption(fmt.Sprintf(`-arrowcolor %s`, optionString(val)))
  5577. }
  5578. // Arrowsize — Styling widgets
  5579. //
  5580. // Arrowsize is a styling option of one or more widgets. Please see
  5581. // [Changing Widget Colors] for details.
  5582. //
  5583. // [Changing Widget Colors]: https://wiki.tcl-lang.org/page/Changing+Widget+Colors
  5584. func Arrowsize(val any) Opt {
  5585. return rawOption(fmt.Sprintf(`-arrosize %s`, optionString(val)))
  5586. }
  5587. // Focusfill — Styling widgets
  5588. //
  5589. // Focusfill is a styling option of a ttk::combobox.
  5590. // More information might be available at the [Tcl/Tk ttk_combobox] page.
  5591. //
  5592. // [Tcl/Tk ttk_combobox]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_combobox.html
  5593. func Focusfill(val any) Opt {
  5594. return rawOption(fmt.Sprintf(`-focusfill %s`, optionString(val)))
  5595. }
  5596. // Fieldbackground — Styling widgets
  5597. //
  5598. // Fieldbackground is a styling option of one or more widgets. Please see
  5599. // [Changing Widget Colors] for details.
  5600. //
  5601. // [Changing Widget Colors]: https://wiki.tcl-lang.org/page/Changing+Widget+Colors
  5602. func Fieldbackground(val any) Opt {
  5603. return rawOption(fmt.Sprintf(`-fieldbackground %s`, optionString(val)))
  5604. }
  5605. // Insertcolor — Styling widgets
  5606. //
  5607. // Insertcolor is a styling option of one or more widgets. Please see
  5608. // [Changing Widget Colors] for details.
  5609. //
  5610. // [Changing Widget Colors]: https://wiki.tcl-lang.org/page/Changing+Widget+Colors
  5611. func Insertcolor(val any) Opt {
  5612. return rawOption(fmt.Sprintf(`-insertcolor %s`, optionString(val)))
  5613. }
  5614. // Postoffset — Styling widgets
  5615. //
  5616. // Postoffset is a styling option of a ttk::combobox.
  5617. // More information might be available at the [Tcl/Tk ttk_combobox] page.
  5618. //
  5619. // [Tcl/Tk ttk_combobox]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_combobox.html
  5620. func Postoffset(val any) Opt {
  5621. return rawOption(fmt.Sprintf(`-postoffset %s`, optionString(val)))
  5622. }
  5623. // Labelmargins — Styling widgets
  5624. //
  5625. // Labelmargins is a styling option of a ttk::labelframe.
  5626. // More information might be available at the [Tcl/Tk ttk_labelframe] page.
  5627. //
  5628. // [Tcl/Tk ttk_labelframe]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_labelframe.html
  5629. func Labelmargins(val any) Opt {
  5630. return rawOption(fmt.Sprintf(`-labelmargins %s`, optionString(val)))
  5631. }
  5632. // Labeloutside — Styling widgets
  5633. //
  5634. // Labeloutside is a styling option of a ttk::labelframe.
  5635. // More information might be available at the [Tcl/Tk ttk_labelframe] page.
  5636. //
  5637. // [Tcl/Tk ttk_labelframe]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_labelframe.html
  5638. func Labeloutside(val any) Opt {
  5639. return rawOption(fmt.Sprintf(`-labeloutside %s`, optionString(val)))
  5640. }
  5641. // Tabmargins — Styling widgets
  5642. //
  5643. // Tabmargins is a styling option of a ttk::notebook.
  5644. // More information might be available at the [Tcl/Tk ttk_notebook] page.
  5645. //
  5646. // [Tcl/Tk ttk_notebook]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_notebook.html
  5647. func Tabmargins(val any) Opt {
  5648. return rawOption(fmt.Sprintf(`-tabmargins %s`, optionString(val)))
  5649. }
  5650. // Tabposition — Styling widgets
  5651. //
  5652. // Tabposition is a styling option of a ttk::notebook.
  5653. //
  5654. // More information might be available at the [Tcl/Tk ttk_notebook] page.
  5655. //
  5656. // [Tcl/Tk ttk_notebook]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_notebook.html
  5657. func Tabposition(val any) Opt {
  5658. return rawOption(fmt.Sprintf(`-tabposition %s`, optionString(val)))
  5659. }
  5660. // Sashthickness — Styling widgets
  5661. //
  5662. // Sashthickness is a styling option of one or more widgets. Please see
  5663. // [Changing Widget Colors] for details.
  5664. //
  5665. // [Changing Widget Colors]: https://wiki.tcl-lang.org/page/Changing+Widget+Colors
  5666. func Sashthickness(val any) Opt {
  5667. return rawOption(fmt.Sprintf(`-sashthickness %s`, optionString(val)))
  5668. }
  5669. // panedwindow — Create and manipulate 'panedwindow' split container widgets
  5670. //
  5671. // # Description
  5672. //
  5673. // Add one or more windows to the panedwindow, each in a separate pane. The
  5674. // arguments consist of the names of one or more windows followed by pairs of
  5675. // arguments that specify how to manage the windows. Option may have any of the
  5676. // values accepted by the configure subcommand.
  5677. //
  5678. // More information might be available at the [Tcl/Tk panedwindow] page.
  5679. //
  5680. // [Tcl/Tk panedwindow]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/panedwindow.html
  5681. func (w *PanedwindowWidget) Add(subwindow *Window, options ...Opt) {
  5682. evalErr(fmt.Sprintf("%s add %s %s", w, subwindow, collect(options...)))
  5683. }
  5684. // panedwindow — Create and manipulate 'panedwindow' split container widgets
  5685. //
  5686. // # Description
  5687. //
  5688. // Query or modify the management options for window. If no option is
  5689. // specified, returns a list describing all of the available options for
  5690. // pathName (see Tk_ConfigureInfo for information on the format of this list).
  5691. // If option is specified with no value, then the command returns a list
  5692. // describing the one named option (this list will be identical to the
  5693. // corresponding sublist of the value returned if no option is specified). If
  5694. // one or more option-value pairs are specified, then the command modifies the
  5695. // given widget option(s) to have the given value(s); in this case the command
  5696. // returns an empty string.
  5697. //
  5698. // More information might be available at the [Tcl/Tk panedwindow] page.
  5699. //
  5700. // [Tcl/Tk panedwindow]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/panedwindow.html
  5701. func (w *PanedwindowWidget) Paneconfigure(subwindow *Window, options ...Opt) string {
  5702. return evalErr(fmt.Sprintf("%s paneconfigure %s %s", w, subwindow, collect(options...)))
  5703. }
  5704. // Stretch option.
  5705. //
  5706. // # Description
  5707. //
  5708. // Controls how extra space is allocated to each of the panes. When is one of
  5709. // always, first, last, middle, and never. The panedwindow will calculate the
  5710. // required size of all its panes. Any remaining (or deficit) space will be
  5711. // distributed to those panes marked for stretching. The space will be
  5712. // distributed based on each panes current ratio of the whole. For the PanedwindowWidget
  5713. // the value should be a string with one of the following definition:
  5714. //
  5715. // - always: This pane will always stretch.
  5716. // - first: Only if this pane is the first pane (left-most or top-most) will it stretch.
  5717. // - last: Only if this pane is the last pane (right-most or bottom-most) will it stretch. This is the default value.
  5718. // - middle: Only if this pane is not the first or last pane will it stretch.
  5719. // - never: This pane will never stretch.
  5720. //
  5721. // For the TTreeviewWidget the value should be a boolean with the following results:
  5722. //
  5723. // - true: This enables stretching for the specified column.
  5724. // - false: This disables stretching for the specified column.
  5725. //
  5726. // Known uses:
  5727. // - [PanedwindowWidget] (command specific)
  5728. // - [TTreeviewWidget] (command specific)
  5729. func Stretch(val any) Opt {
  5730. return rawOption(fmt.Sprintf(`-stretch %s`, optionString(val)))
  5731. }
  5732. // panedwindow — Create and manipulate 'panedwindow' split container widgets
  5733. //
  5734. // # Description
  5735. //
  5736. // Query a management option for window. Option may be any value allowed by the
  5737. // paneconfigure subcommand.
  5738. //
  5739. // More information might be available at the [Tcl/Tk panedwindow] page.
  5740. //
  5741. // [Tcl/Tk panedwindow]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/panedwindow.html
  5742. func (w *PanedwindowWidget) Panecget(subwindow *Window, opt any) string {
  5743. return evalErr(fmt.Sprintf("%s panecget %s %s", w, subwindow, funcToTclOption(opt)))
  5744. }
  5745. // ttk::panedwindow — Multi-pane container window
  5746. //
  5747. // # Description
  5748. //
  5749. // Adds a new pane to the window. See PANE OPTIONS for the list of available options.
  5750. //
  5751. // More information might be available at the [Tcl/Tk ttk_panedwindow] page.
  5752. //
  5753. // [Tcl/Tk ttk_panedwindow]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/panedwindow.html
  5754. func (w *TPanedwindowWidget) Add(subwindow *Window, options ...Opt) {
  5755. evalErr(fmt.Sprintf("%s add %s %s", w, subwindow, collect(options...)))
  5756. }
  5757. // Gripsize — Styling widgets
  5758. //
  5759. // Gripsize is a styling option of a ttk::panedwindow and ttk::scrollbar.
  5760. // More information might be available at the [Tcl/Tk ttk_panedwindow] or
  5761. // [Tcl/Tk ttk_scrollbar] page.
  5762. //
  5763. // [Tcl/Tk ttk_panedwindow]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/panedwindow.html
  5764. // [Tcl/Tk ttk_scrollbar]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_scrollbar.html
  5765. func Gripsize(val any) Opt {
  5766. return rawOption(fmt.Sprintf(`-tabposition %s`, optionString(val)))
  5767. }
  5768. // Maxphase — Styling widgets
  5769. //
  5770. // Maxphase is a styling option of a ttk::progressbar.
  5771. // More information might be available at the [Tcl/Tk ttk_progressbar] page.
  5772. //
  5773. // [Tcl/Tk ttk_progressbar]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_progressbar.html
  5774. func Maxphase(val any) Opt {
  5775. return rawOption(fmt.Sprintf(`-maxphase %s`, optionString(val)))
  5776. }
  5777. // Period — Styling widgets
  5778. //
  5779. // Period is a styling option of a ttk::progressbar.
  5780. // More information might be available at the [Tcl/Tk ttk_progressbar] page.
  5781. //
  5782. // [Tcl/Tk ttk_progressbar]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_progressbar.html
  5783. func Period(val any) Opt {
  5784. return rawOption(fmt.Sprintf(`-period %s`, optionString(val)))
  5785. }
  5786. // Groovewidth — Styling widgets
  5787. //
  5788. // Groovewidth is a styling option of a ttk::scale.
  5789. // More information might be available at the [Tcl/Tk ttk_scale] page.
  5790. //
  5791. // [Tcl/Tk ttk_scale]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_scale.html
  5792. func Groovewidth(val any) Opt {
  5793. return rawOption(fmt.Sprintf(`-groovewidth %s`, optionString(val)))
  5794. }
  5795. // Sliderwidth — Styling widgets
  5796. //
  5797. // Sliderwidth is a styling option of a ttk::scale.
  5798. // More information might be available at the [Tcl/Tk ttk_scale] page.
  5799. //
  5800. // [Tcl/Tk ttk_scale]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_scale.html
  5801. func Sliderwidth(val any) Opt {
  5802. return rawOption(fmt.Sprintf(`-sliderwidth %s`, optionString(val)))
  5803. }
  5804. // Troughrelief — Styling widgets
  5805. //
  5806. // Troughrelief is a styling option of one or more widgets. Please see
  5807. // [Changing Widget Colors] for details.
  5808. //
  5809. // [Changing Widget Colors]: https://wiki.tcl-lang.org/page/Changing+Widget+Colors
  5810. func Troughrelief(val any) Opt {
  5811. return rawOption(fmt.Sprintf(`-troughrelief %s`, optionString(val)))
  5812. }
  5813. // Indent — Styling widgets
  5814. //
  5815. // Indent is a styling option of a ttk::treeview.
  5816. // More information might be available at the [Tcl/Tk ttk_treeview] page.
  5817. //
  5818. // [Tcl/Tk ttk_treeview]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_treeview.html
  5819. func Indent(val any) Opt {
  5820. return rawOption(fmt.Sprintf(`-indent %s`, optionString(val)))
  5821. }
  5822. // Columnseparatorwidth — Styling widgets
  5823. //
  5824. // Columnseparatorwidth is a styling option of a ttk::treeview.
  5825. // More information might be available at the [Tcl/Tk ttk_treeview] page.
  5826. //
  5827. // [Tcl/Tk ttk_treeview]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_treeview.html
  5828. func Columnseparatorwidth(val any) Opt {
  5829. return rawOption(fmt.Sprintf(`-columnseparatorwidth %s`, optionString(val)))
  5830. }
  5831. // Rowheight — Styling widgets
  5832. //
  5833. // Rowheight is a styling option of one or more widgets. Please see
  5834. // [Changing Widget Colors] for details.
  5835. //
  5836. // [Changing Widget Colors]: https://wiki.tcl-lang.org/page/Changing+Widget+Colors
  5837. func Rowheight(val any) Opt {
  5838. return rawOption(fmt.Sprintf(`-rowheight %s`, optionString(val)))
  5839. }
  5840. // Stripedbackground — Styling widgets
  5841. //
  5842. // Stripedbackground is a styling option of a ttk::treeview.
  5843. // More information might be available at the [Tcl/Tk ttk_treeview] page.
  5844. //
  5845. // [Tcl/Tk ttk_treeview]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_treeview.html
  5846. func Stripedbackground(val any) Opt {
  5847. return rawOption(fmt.Sprintf(`-stripedbackground %s`, optionString(val)))
  5848. }
  5849. // Indicatormargins — Styling widgets
  5850. //
  5851. // Indicatormargins is a styling option of a ttk::treeview.
  5852. // More information might be available at the [Tcl/Tk ttk_treeview] page.
  5853. //
  5854. // [Tcl/Tk ttk_treeview]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_treeview.html
  5855. func Indicatormargins(val any) Opt {
  5856. return rawOption(fmt.Sprintf(`-indicatormargins %s`, optionString(val)))
  5857. }
  5858. // Indicatorsize — Styling widgets
  5859. //
  5860. // Indicatorsize is a styling option of a ttk::treeview.
  5861. // More information might be available at the [Tcl/Tk ttk_treeview] page.
  5862. //
  5863. // [Tcl/Tk ttk_treeview]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_treeview.html
  5864. func Indicatorsize(val any) Opt {
  5865. return rawOption(fmt.Sprintf(`-indicatorsize %s`, optionString(val)))
  5866. }
  5867. // Topmost option.
  5868. //
  5869. // Known uses:
  5870. // - [WmAttributes] (command specific)
  5871. func Topmost(v bool) Opt {
  5872. return rawOption(fmt.Sprintf(`-topmost %s`, optionString(v)))
  5873. }
  5874. // Type option.
  5875. //
  5876. // Known uses:
  5877. // - [ClipboardAppend] (command specific)
  5878. // - [ClipboardGet] (command specific)
  5879. // - [Menu] (widget specific)
  5880. // - [MessageBox] (command specific)
  5881. // - [WmAttributes] (command specific)
  5882. func Type(val any) Opt {
  5883. return rawOption(fmt.Sprintf(`-type %s`, optionString(val)))
  5884. }
  5885. // Type — Get the configured option value.
  5886. //
  5887. // Known uses:
  5888. // - [Menu] (widget specific)
  5889. // - [WmAttributes] (command specific)
  5890. func (w *Window) Type() string {
  5891. return evalErr(fmt.Sprintf(`%s cget -type`, w))
  5892. }
  5893. // wm — Communicate with window manager
  5894. //
  5895. // # Description
  5896. //
  5897. // - wm attributes window
  5898. // - wm attributes window ?option?
  5899. // - wm attributes window ?option value option value...?
  5900. //
  5901. // This subcommand returns or sets platform specific attributes associated with
  5902. // a window. The first form returns a list of the platform specific flags and
  5903. // their values. The second form returns the value for the specific option. The
  5904. // third form sets one or more of the values. The values are as follows:
  5905. //
  5906. // [Topmost]: Specifies whether this is a topmost window (displays above all other windows).
  5907. //
  5908. // [Type]: Requests that the window should be interpreted by the window manager
  5909. // as being of the specified type(s). This may cause the window to be decorated
  5910. // in a different way or otherwise managed differently, though exactly what
  5911. // happens is entirely up to the window manager. A list of types may be used,
  5912. // in order of preference. The following values are mapped to constants defined
  5913. // in the EWMH specification (using others is possible, but not advised):
  5914. //
  5915. // - "desktop"
  5916. // Indicates a desktop feature.
  5917. // - "dock"
  5918. // Indicates a dock/panel feature.
  5919. // - "toolbar"
  5920. // Indicates a toolbar window that should be acting on behalf of another
  5921. // window, as indicated with wm transient.
  5922. // - "menu"
  5923. // Indicates a torn-off menu that should be acting on behalf of another
  5924. // window, as indicated with wm transient.
  5925. // - "utility"
  5926. // Indicates a utility window (e.g., palette or toolbox) that should be acting
  5927. // on behalf of another window, as indicated with wm transient.
  5928. // - "splash"
  5929. // Indicates a splash screen, displayed during application start up.
  5930. // - "dialog"
  5931. // Indicates a general dialog window, that should be acting on behalf of
  5932. // another window, as indicated with wm transient.
  5933. // - "dropdownMenu"
  5934. // Indicates a menu summoned from a menu bar, which should usually also be set
  5935. // to be override-redirected (with wm overrideredirect).
  5936. // - "popupMenu"
  5937. // Indicates a popup menu, which should usually also be set to be
  5938. // override-redirected (with wm overrideredirect).
  5939. // - "tooltip"
  5940. // Indicates a tooltip window, which should usually also be set to be
  5941. // override-redirected (with wm overrideredirect).
  5942. // - "notification"
  5943. // Indicates a window that provides a background notification of some event,
  5944. // which should usually also be set to be override-redirected (with wm
  5945. // overrideredirect).
  5946. // - "combo"
  5947. // Indicates the drop-down list of a combobox widget, which should usually
  5948. // also be set to be override-redirected (with wm overrideredirect).
  5949. // - "dnd"
  5950. // Indicates a window that represents something being dragged, which should
  5951. // usually also be set to be override-redirected (with wm overrideredirect).
  5952. // - "normal"
  5953. // Indicates a window that has no special interpretation.
  5954. //
  5955. // More information might be available at the [Tcl/Tk wm] page.
  5956. //
  5957. // [Tcl/Tk wm]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/wm.html
  5958. func WmAttributes(w *Window, options ...any) string {
  5959. switch len(options) {
  5960. case 0:
  5961. return evalErr(fmt.Sprintf("wm attributes %s", w))
  5962. case 1:
  5963. if s := funcToTclOption(options[0]); s != "" {
  5964. return evalErr(fmt.Sprintf("wm attributes %s %s", w, s))
  5965. }
  5966. fallthrough
  5967. default:
  5968. return evalErr(fmt.Sprintf("wm attributes %s %s", w, collectAny(options...)))
  5969. }
  5970. }
  5971. // wm — Communicate with window manager
  5972. //
  5973. // # Description
  5974. //
  5975. // This command is used to manage window manager protocols. The name argument
  5976. // in the wm protocol command is the name of an atom corresponding to a window
  5977. // manager protocol. Examples include WM_DELETE_WINDOW or WM_SAVE_YOURSELF or
  5978. // WM_TAKE_FOCUS. A window manager protocol is a class of messages sent from a
  5979. // window manager to a Tk application outside of the normal event processing
  5980. // system. The main example is the WM_DELETE_WINDOW protocol; these messages
  5981. // are sent when the user clicks the close widget in the title bar of a window.
  5982. // Handlers for window manager protocols are installed with the wm protocol
  5983. // command. As a rule, if no handler has been installed for a protocol by the
  5984. // wm protocol command then all messages of that protocol are ignored. The
  5985. // WM_DELETE_WINDOW protocol is an exception to this rule. At start-up Tk
  5986. // installs a handler for this protocol, which responds by destroying the
  5987. // window. The wm protocol command can be used to replace this default handler
  5988. // by one which responds differently.
  5989. //
  5990. // A common requirement is to make sure that even if the user clicks the
  5991. // application's close button (X) a close handling function will be
  5992. // called (e.g., to prompt to save unsaved changes). For example, to
  5993. // ensure a custom func onQuit() function is called use:
  5994. //
  5995. // WmProtocol(App, "WM_DELETE_WINDOW", onQuit)
  5996. //
  5997. // The list of available window manager protocols depends on the window
  5998. // manager, but all window managers supported by Tk provide WM_DELETE_WINDOW.
  5999. // On the Windows platform, a WM_SAVE_YOURSELF message is sent on user logout
  6000. // or system restart.
  6001. //
  6002. // If both name and command are specified, then command becomes the handler for
  6003. // the protocol specified by name. The atom for name will be added to window's
  6004. // WM_PROTOCOLS property to tell the window manager that the application has a
  6005. // handler for the protocol specified by name, and command will be invoked in
  6006. // the future whenever the window manager sends a message of that protocol to
  6007. // the Tk application. In this case the wm protocol command returns an empty
  6008. // string. If name is specified but command is not (is nil), then the current
  6009. // handler for name is returned, or an empty string if there is no handler
  6010. // defined for name (as a special case, the default handler for
  6011. // WM_DELETE_WINDOW is not returned). If command is specified as an empty
  6012. // string then the atom for name is removed from the WM_PROTOCOLS property of
  6013. // window and the handler is destroyed; an empty string is returned. Lastly, if
  6014. // neither name nor command is specified, the wm protocol command returns a
  6015. // list of all of the protocols for which handlers are currently defined for
  6016. // window.
  6017. //
  6018. // More information might be available at the [Tcl/Tk wm] page.
  6019. //
  6020. // [Tcl/Tk wm]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/wm.html
  6021. func WmProtocol(w *Window, name string, command any) string {
  6022. switch {
  6023. case command == nil:
  6024. return evalErr(fmt.Sprintf("wm protocol %s %s", w, tclSafeString(name)))
  6025. case command == "":
  6026. return evalErr(fmt.Sprintf("wm protocol %s %s {}", w, tclSafeString(name)))
  6027. default:
  6028. switch x := command.(type) {
  6029. case *eventHandler:
  6030. x.tcl = ""
  6031. return evalErr(fmt.Sprintf("wm protocol %s %s %s", w, tclSafeString(name), collect(x)))
  6032. default:
  6033. return evalErr(fmt.Sprintf("wm protocol %s %s %s", w, tclSafeString(name), newEventHandler("", command).optionString(w)))
  6034. }
  6035. }
  6036. }
  6037. // wm — Communicate with window manager
  6038. //
  6039. // # Description
  6040. //
  6041. // If container is specified, then the window manager is informed that window
  6042. // is a transient window (e.g. pull-down menu) working on behalf of container
  6043. // (where container is the path name for a top-level window). If container is
  6044. // specified as an empty string then window is marked as not being a transient
  6045. // window any more. Otherwise the command returns the path name of window's
  6046. // current container, or an empty string if window is not currently a transient
  6047. // window. A transient window will mirror state changes in the container and
  6048. // inherit the state of the container when initially mapped. The directed graph
  6049. // with an edge from each transient to its container must be acyclic. In
  6050. // particular, it is an error to attempt to make a window a transient of
  6051. // itself. The window manager may also decorate a transient window differently,
  6052. // removing some features normally present (e.g., minimize and maximize
  6053. // buttons) though this is entirely at the discretion of the window manager.
  6054. //
  6055. // More information might be available at the [Tcl/Tk wm] page.
  6056. //
  6057. // [Tcl/Tk wm]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/wm.html
  6058. func WmTransient(options ...Opt) string {
  6059. return evalErr(fmt.Sprintf("wm transient %s", collect(options...)))
  6060. }
  6061. // wm — Communicate with window manager
  6062. //
  6063. // # Description
  6064. //
  6065. // Arrange for window to be iconified. It window has not yet been mapped for
  6066. // the first time, this command will arrange for it to appear in the iconified
  6067. // state when it is eventually mapped.
  6068. //
  6069. // More information might be available at the [Tcl/Tk wm] page.
  6070. //
  6071. // [Tcl/Tk wm]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/wm.html
  6072. func WmIconify(w *Window) {
  6073. if w == App {
  6074. appIconified = true
  6075. appDeiconified = false
  6076. }
  6077. wmIconify(w)
  6078. }
  6079. func wmIconify(w *Window) {
  6080. evalErr(fmt.Sprintf("wm iconify %s", w))
  6081. }
  6082. // wm — Communicate with window manager
  6083. //
  6084. // # Description
  6085. //
  6086. // Arrange for window to be displayed in normal (non-iconified) form. This is
  6087. // done by mapping the window. If the window has never been mapped then this
  6088. // command will not map the window, but it will ensure that when the window is
  6089. // first mapped it will be displayed in de-iconified form. On Windows, a
  6090. // deiconified window will also be raised and be given the focus (made the
  6091. // active window). Returns an empty string.
  6092. //
  6093. // More information might be available at the [Tcl/Tk wm] page.
  6094. //
  6095. // [Tcl/Tk wm]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/wm.html
  6096. func WmDeiconify(w *Window) {
  6097. if w == App {
  6098. appDeiconified = true
  6099. appIconified = false
  6100. }
  6101. wmDeiconify(w)
  6102. }
  6103. func wmDeiconify(w *Window) {
  6104. evalErr(fmt.Sprintf("wm deiconify %s", w))
  6105. }
  6106. // wm — Communicate with window manager
  6107. //
  6108. // # Description
  6109. //
  6110. // Arranges for window to be withdrawn from the screen. This causes the window
  6111. // to be unmapped and forgotten about by the window manager. If the window has
  6112. // never been mapped, then this command causes the window to be mapped in the
  6113. // withdrawn state. Not all window managers appear to know how to handle
  6114. // windows that are mapped in the withdrawn state. Note that it sometimes seems
  6115. // to be necessary to withdraw a window and then re-map it (e.g. with wm
  6116. // deiconify) to get some window managers to pay attention to changes in window
  6117. // attributes such as group.
  6118. //
  6119. // More information might be available at the [Tcl/Tk wm] page.
  6120. //
  6121. // [Tcl/Tk wm]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/wm.html
  6122. func WmWithdraw(w *Window) {
  6123. if w == App {
  6124. appWithdrawn = true
  6125. }
  6126. wmWithdraw(w)
  6127. }
  6128. func wmWithdraw(w *Window) {
  6129. evalErr(fmt.Sprintf("wm withdraw %s", w))
  6130. }
  6131. // wm — Communicate with window manager
  6132. //
  6133. // # Description
  6134. //
  6135. // If newGeometry is specified, then the geometry of window is changed and an
  6136. // empty string is returned. Otherwise the current geometry for window is
  6137. // returned (this is the most recent geometry specified either by manual
  6138. // resizing or in a wm geometry command). NewGeometry has the form
  6139. // =widthxheight±x±y, where any of =, widthxheight, or ±x±y may be omitted.
  6140. // Width and height are positive integers specifying the desired dimensions of
  6141. // window. If window is gridded (see GRIDDED GEOMETRY MANAGEMENT below) then
  6142. // the dimensions are specified in grid units; otherwise they are specified in
  6143. // pixel units.
  6144. //
  6145. // X and y specify the desired location of window on the screen, in pixels. If
  6146. // x is preceded by +, it specifies the number of pixels between the left edge
  6147. // of the screen and the left edge of window's border; if preceded by - then x
  6148. // specifies the number of pixels between the right edge of the screen and the
  6149. // right edge of window's border. If y is preceded by + then it specifies the
  6150. // number of pixels between the top of the screen and the top of window's
  6151. // border; if y is preceded by - then it specifies the number of pixels between
  6152. // the bottom of window's border and the bottom of the screen.
  6153. //
  6154. // If newGeometry is specified as an empty string then any existing
  6155. // user-specified geometry for window is cancelled, and the window will revert
  6156. // to the size requested internally by its widgets.
  6157. //
  6158. // Note that this is related to winfo geometry, but not the same. That can only
  6159. // query the geometry, and always reflects Tk's current understanding of the
  6160. // actual size and location of window, whereas wm geometry allows both setting
  6161. // and querying of the window manager's understanding of the size and location
  6162. // of the window. This can vary significantly, for example to reflect the
  6163. // addition of decorative elements to window such as title bars, and window
  6164. // managers are not required to precisely follow the requests made through this
  6165. // command.
  6166. //
  6167. // More information might be available at the [Tcl/Tk wm] page.
  6168. //
  6169. // [Tcl/Tk wm]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/wm.html
  6170. func WmGeometry(w *Window, geometry ...string) string {
  6171. // https://gitlab.com/cznic/tk9.0/-/commit/94774b2ee20e8d417f8eb12fa838eb9dcf58e8c6#note_2314759986
  6172. switch {
  6173. case len(geometry) == 0:
  6174. return evalErr(fmt.Sprintf("wm geometry %s", w))
  6175. default:
  6176. if w == App {
  6177. autocenterDisabled = true
  6178. }
  6179. return evalErr(fmt.Sprintf("wm geometry %s %s", w, tclSafeString(geometry[0])))
  6180. }
  6181. }
  6182. // wm — Communicate with window manager
  6183. //
  6184. // # Description
  6185. //
  6186. // Width and height give the maximum permissible
  6187. // dimensions for window. For gridded windows the dimensions are specified in
  6188. // grid units; otherwise they are specified in pixel units. The window manager
  6189. // will restrict the window's dimensions to be less than or equal to width and
  6190. // height. If width and height are specified, then the command returns an empty
  6191. // string. Otherwise it returns a Tcl list with two elements, which are the
  6192. // maximum width and height currently in effect. The maximum size defaults to
  6193. // the size of the screen. See the sections on geometry management below for
  6194. // more information.
  6195. //
  6196. // More information might be available at the [Tcl/Tk wm] page.
  6197. //
  6198. // [Tcl/Tk wm]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/wm.html
  6199. func WmSetMaxSize(w *Window, width, height int) {
  6200. evalErr(fmt.Sprintf("wm maxsize %s %v %v", w, width, height))
  6201. }
  6202. // wm — Communicate with window manager
  6203. //
  6204. // # Description
  6205. //
  6206. // Returns the maximum width and height currently in effect. The maximum size defaults to
  6207. // the size of the screen. See the sections on geometry management below for
  6208. // more information.
  6209. //
  6210. // More information might be available at the [Tcl/Tk wm] page.
  6211. //
  6212. // [Tcl/Tk wm]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/wm.html
  6213. func WmMaxSize(w *Window) (width, height int) {
  6214. a := strings.Fields(evalErr(fmt.Sprintf("wm maxsize %s", w)))
  6215. if len(a) != 2 {
  6216. return -1, -1
  6217. }
  6218. var err error
  6219. if width, err = strconv.Atoi(a[0]); err != nil {
  6220. return -1, -1
  6221. }
  6222. if height, err = strconv.Atoi(a[1]); err != nil {
  6223. return -1, -1
  6224. }
  6225. return width, height
  6226. }
  6227. // wm — Communicate with window manager
  6228. //
  6229. // # Description
  6230. //
  6231. // If width and height are specified, they give the minimum permissible
  6232. // dimensions for window. For gridded windows the dimensions are specified in
  6233. // grid units; otherwise they are specified in pixel units. The window manager
  6234. // will restrict the window's dimensions to be greater than or equal to width
  6235. // and height. If width and height are specified, then the command returns an
  6236. // empty string. Otherwise it returns a Tcl list with two elements, which are
  6237. // the minimum width and height currently in effect. The minimum size defaults
  6238. // to one pixel in each dimension. See the sections on geometry management
  6239. // below for more information.
  6240. //
  6241. // More information might be available at the [Tcl/Tk wm] page.
  6242. //
  6243. // [Tcl/Tk wm]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/wm.html
  6244. func WmMinSize(w *Window, widthHeight ...any) (r string) {
  6245. arg := ""
  6246. if len(widthHeight) >= 2 {
  6247. arg = fmt.Sprintf("%s %s", tclSafeString(fmt.Sprint(widthHeight[0])), tclSafeString(fmt.Sprint(widthHeight[1])))
  6248. }
  6249. return evalErr(fmt.Sprintf("wm minsize %s %s", w, arg))
  6250. }
  6251. // Initalize enforces the parts of package initialization that are otherwise
  6252. // done lazily. The function may panic if ErrorMode is PanicOnError.
  6253. func Initialize() {
  6254. lazyInit()
  6255. }
  6256. // ttk::notebook — Multi-paned container widget
  6257. //
  6258. // # Description
  6259. //
  6260. // Adds a new tab to the notebook. See TAB OPTIONS for the list of available
  6261. // options. If window is currently managed by the notebook but hidden, it is
  6262. // restored to its previous position.
  6263. //
  6264. // More information might be available at the [Tcl/Tk TNotebook] page.
  6265. //
  6266. // [Tcl/Tk TNotebook]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_notebook.html
  6267. func (w *TNotebookWidget) Add(options ...Opt) {
  6268. evalErr(fmt.Sprintf("%s add %v", w, winCollect(w.Window, options...)))
  6269. }
  6270. // TNotebook — Multi-paned container widget
  6271. //
  6272. // # Description
  6273. //
  6274. // Selects the specified tab. The associated content window will be displayed,
  6275. // and the previously-selected window (if different) is unmapped. If tabid is
  6276. // omitted, returns the widget name of the currently selected pane.
  6277. //
  6278. // More information might be available at the [Tcl/Tk TNotebook] page.
  6279. //
  6280. // [Tcl/Tk TNotebook]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_notebook.html
  6281. func (w *TNotebookWidget) Select(tabid any) string {
  6282. var arg string
  6283. if tabid != nil && tabid != "" {
  6284. arg = tclSafeString(fmt.Sprint(tabid))
  6285. }
  6286. return evalErr(fmt.Sprintf("%s select %s", w, arg))
  6287. }
  6288. // TNotebook — Multi-paned container widget
  6289. //
  6290. // # Description
  6291. //
  6292. // Returns the list of windows managed by the notebook, in the index order of
  6293. // their associated tabs.
  6294. //
  6295. // More information might be available at the [Tcl/Tk TNotebook] page.
  6296. //
  6297. // [Tcl/Tk TNotebook]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_notebook.html
  6298. func (w *TNotebookWidget) Tabs() (r []*Window) {
  6299. a := parseList(evalErr(fmt.Sprintf("%s tabs", w)))
  6300. for _, v := range a {
  6301. r = append(r, windowIndex[v])
  6302. }
  6303. return r
  6304. }
  6305. // tk_dialog — Create modal dialog and wait for response
  6306. //
  6307. // # Description
  6308. //
  6309. // This procedure is part of the Tk script library. It is largely deprecated by
  6310. // the tk_messageBox. Its arguments describe a dialog box:
  6311. //
  6312. // - window - Name of top-level window to use for dialog. Any existing window
  6313. // by this name is destroyed.
  6314. //
  6315. // - title - Text to appear in the window manager's title bar for the dialog.
  6316. //
  6317. // - text - Message to appear in the top portion of the dialog box.
  6318. //
  6319. // - bitmap - If non-empty, specifies a bitmap (in a form suitable for
  6320. // Tk_GetBitmap) to display in the top portion of the dialog, to the left of
  6321. // the text. If this is an empty string then no bitmap is displayed in the
  6322. // dialog.
  6323. //
  6324. // - defaultButton - If this is an integer greater than or equal to zero, then it
  6325. // gives the index of the button that is to be the default button for the
  6326. // dialog (0 for the leftmost button, and so on). If negative or an empty
  6327. // string then there will not be any default button.
  6328. //
  6329. // - buttons - There will be one button for each of these arguments. Each string
  6330. // specifies text to display in a button, in order from left to right.
  6331. //
  6332. // After creating a dialog box, tk_dialog waits for the user to select one of
  6333. // the buttons either by clicking on the button with the mouse or by typing
  6334. // return to invoke the default button (if any). Then it returns the index of
  6335. // the selected button: 0 for the leftmost button, 1 for the button next to it,
  6336. // and so on. If the dialog's window is destroyed before the user selects one
  6337. // of the buttons, then -1 is returned.
  6338. //
  6339. // While waiting for the user to respond, tk_dialog sets a local grab. This
  6340. // prevents the user from interacting with the application in any way except to
  6341. // invoke the dialog box.
  6342. // func Dialog(window *Window, title, text, bitmap string, defaultButton int, buttons ...string) (r int) {
  6343. // s := evalErr(fmt.Sprintf("tk_dialog %s %s %s", window, tclSafeStrings(title, text, bitmap), tclSafeStrings(buttons...)))
  6344. // if s == "" {
  6345. // return -1
  6346. // }
  6347. //
  6348. // var err error
  6349. // if r, err = strconv.Atoi(s); err != nil {
  6350. // fail(err)
  6351. // return -1
  6352. // }
  6353. //
  6354. // return r
  6355. // }
  6356. type Ticker struct {
  6357. eh *eventHandler
  6358. }
  6359. func NewTicker(d time.Duration, handler func()) (r *Ticker, err error) {
  6360. eh := newEventHandler("", handler)
  6361. nm := fmt.Sprintf("ticker%v", id.Add(1))
  6362. if _, err = eval(fmt.Sprintf(`proc %s {} {
  6363. after %v {
  6364. eventDispatcher %v
  6365. %[1]s
  6366. }
  6367. }
  6368. %[1]s
  6369. `, nm, d.Milliseconds(), eh.id)); err != nil {
  6370. return nil, err
  6371. }
  6372. return &Ticker{eh: eh}, nil
  6373. }
  6374. // ttk::checkbutton — On/off widget
  6375. //
  6376. // # Description
  6377. //
  6378. // Toggles between the selected and deselected states and evaluates the
  6379. // associated -command. If the widget is currently selected, sets the -variable
  6380. // to the -offvalue and deselects the widget; otherwise, sets the -variable to
  6381. // the -onvalue. Returns the result of the -command.
  6382. //
  6383. // More information might be available at the [Tcl/Tk TCheckbutton] page.
  6384. //
  6385. // [Tcl/Tk TCheckbutton]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_checkbutton.html
  6386. func (w *TCheckbuttonWidget) Invoke() string {
  6387. return evalErr(fmt.Sprintf("%s invoke", w))
  6388. }
  6389. // // ttk::checkbutton — On/off widget
  6390. // //
  6391. // // # Description
  6392. // //
  6393. // // Set the on/off state of 'w'.
  6394. // func (w *TCheckbuttonWidget) Set(on bool) string {
  6395. // return evalErr(fmt.Sprintf("set %s %v", w.variable(cfgVar), on))
  6396. // }
  6397. //
  6398. // func cfgVar(w *Window, nm string) {
  6399. // w.Configure(Variable(nm))
  6400. // }
  6401. //
  6402. // func (w *Window) variable(reg func(w *Window, nm string)) (r string) {
  6403. // if r, ok := variables[w]; ok {
  6404. // return r
  6405. // }
  6406. //
  6407. // r = fmt.Sprintf("::tk9var%d", id.Add(1))
  6408. // variables[w] = r
  6409. // if reg != nil {
  6410. // reg(w, r)
  6411. // }
  6412. // return r
  6413. // }
  6414. //
  6415. // // ttk::checkbutton — On/off widget
  6416. // //
  6417. // // # Description
  6418. // //
  6419. // // Get the on/off state of 'w'.
  6420. // func (w *TCheckbuttonWidget) Get() bool {
  6421. // return toBool(evalErr(fmt.Sprintf("return $%s", w.variable(cfgVar))))
  6422. // }
  6423. //
  6424. // func toBool(s string) (r bool) {
  6425. // switch s {
  6426. // case "false", "0":
  6427. // return false
  6428. // case "true", "1":
  6429. // return true
  6430. // }
  6431. //
  6432. // fail(fmt.Errorf("invalid boolean: %q", s))
  6433. // return false
  6434. // }
  6435. // checkbutton — Create and manipulate 'checkbutton' boolean selection widgets
  6436. //
  6437. // # Description
  6438. //
  6439. // Selects the checkbutton and sets the associated variable to its “on” value.
  6440. //
  6441. // More information might be available at the [Tcl/Tk checkbutton] page.
  6442. //
  6443. // [Tcl/Tk checkbutton]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/checkbutton.html
  6444. func (w *CheckbuttonWidget) Select() {
  6445. evalErr(fmt.Sprintf("%s select", w))
  6446. }
  6447. // checkbutton — Create and manipulate 'checkbutton' boolean selection widgets
  6448. //
  6449. // # Description
  6450. //
  6451. // Does just what would have happened if the user invoked the checkbutton with
  6452. // the mouse: toggle the selection state of the button and invoke the Tcl
  6453. // command associated with the checkbutton, if there is one. The return value
  6454. // is the return value from the Tcl command, or an empty string if there is no
  6455. // command associated with the checkbutton. This command is ignored if the
  6456. // checkbutton's state is disabled.
  6457. //
  6458. // More information might be available at the [Tcl/Tk checkbutton] page.
  6459. //
  6460. // [Tcl/Tk checkbutton]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/checkbutton.html
  6461. func (w *CheckbuttonWidget) Invoke() string {
  6462. return evalErr(fmt.Sprintf("%s invoke", w))
  6463. }
  6464. // checkbutton — Create and manipulate 'checkbutton' boolean selection widgets
  6465. //
  6466. // # Description
  6467. //
  6468. // Deselects the checkbutton and sets the associated variable to its “off” value.
  6469. //
  6470. // More information might be available at the [Tcl/Tk checkbutton] page.
  6471. //
  6472. // [Tcl/Tk checkbutton]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/checkbutton.html
  6473. func (w *CheckbuttonWidget) Deselect() {
  6474. evalErr(fmt.Sprintf("%s deselect", w))
  6475. }
  6476. // font — Create and inspect fonts.
  6477. //
  6478. // # Description
  6479. //
  6480. // Query or modify the desired attributes for the named font called fontname.
  6481. // If no option is specified, returns a list describing all the options and
  6482. // their values for fontname. If a single option is specified with no value,
  6483. // then returns the current value of that attribute. If one or more
  6484. // option-value pairs are specified, then the command modifies the given named
  6485. // font to have the given values; in this case, all widgets using that font
  6486. // will redisplay themselves using the new attributes for the font. See FONT
  6487. // OPTIONS below for a list of the possible attributes.
  6488. //
  6489. // Note that on Aqua/macOS, the system fonts (see PLATFORM SPECIFIC FONTS
  6490. // below) may not be actually altered because they are implemented by the
  6491. // system theme. To achieve the effect of modification, use font actual to get
  6492. // their configuration and font create to synthesize a copy of the font which
  6493. // can be modified.
  6494. //
  6495. // More information might be available at the [Tcl/Tk font] page.
  6496. //
  6497. // [Tcl/Tk font]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/font.html
  6498. func FontConfigure(name string, options ...any) []string {
  6499. for i, v := range options {
  6500. if s := funcToTclOption(v); s != "" {
  6501. options[i] = rawOption(s)
  6502. }
  6503. }
  6504. return parseList(evalErr(fmt.Sprintf("font configure %s %s", tclSafeString(name), collectAny(options...))))
  6505. }
  6506. // Data option.
  6507. //
  6508. // Known uses:
  6509. // - [NewBitmap] (command specific)
  6510. // - [NewPhoto] (command specific)
  6511. func Data(val any) Opt {
  6512. return rawOption(fmt.Sprintf(`-data %s`, optionString(val)))
  6513. }
  6514. // winfo — Return window-related information
  6515. //
  6516. // # Description
  6517. //
  6518. // Returns a slice of all the children of window. Top-level windows are
  6519. // returned as children of their logical parents. The list is in stacking
  6520. // order, with the lowest window first, except for Top-level windows which are
  6521. // not returned in stacking order. Use the wm stackorder command to query the
  6522. // stacking order of Top-level windows.
  6523. //
  6524. // More information might be available at the [Tcl/Tk winfo] page.
  6525. //
  6526. // [Tcl/Tk winfo]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/winfo.html
  6527. func WinfoChildren(w *Window) (r []*Window) {
  6528. for _, v := range parseList(evalErr(fmt.Sprintf("winfo children %s", w))) {
  6529. if w := windowIndex[v]; w != nil {
  6530. r = append(r, w)
  6531. }
  6532. }
  6533. return r
  6534. }
  6535. // winfo — Return window-related information
  6536. //
  6537. // # Description
  6538. //
  6539. // Returns a decimal string giving the height of window's screen, in pixels.
  6540. //
  6541. // More information might be available at the [Tcl/Tk winfo] page.
  6542. //
  6543. // [Tcl/Tk winfo]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/winfo.html
  6544. func WinfoScreenHeight(w *Window) string {
  6545. return evalErr(fmt.Sprintf("winfo screenheight %s", w))
  6546. }
  6547. // winfo — Return window-related information
  6548. //
  6549. // # Description
  6550. //
  6551. // Returns a decimal string giving the width of window's screen, in pixels.
  6552. //
  6553. // More information might be available at the [Tcl/Tk winfo] page.
  6554. //
  6555. // [Tcl/Tk winfo]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/winfo.html
  6556. func WinfoScreenWidth(w *Window) string {
  6557. return evalErr(fmt.Sprintf("winfo screenwidth %s", w))
  6558. }
  6559. // winfo — Return window-related information
  6560. //
  6561. // # Description
  6562. //
  6563. // Returns a decimal string giving window's height in pixels. When a window is
  6564. // first created its height will be 1 pixel; the height will eventually be
  6565. // changed by a geometry manager to fulfil the window's needs. If you need the
  6566. // true height immediately after creating a widget, invoke update to force the
  6567. // geometry manager to arrange it, or use winfo reqheight to get the window's
  6568. // requested height instead of its actual height.
  6569. //
  6570. // More information might be available at the [Tcl/Tk winfo] page.
  6571. //
  6572. // [Tcl/Tk winfo]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/winfo.html
  6573. func WinfoHeight(w *Window) string {
  6574. return evalErr(fmt.Sprintf("winfo height %s", w))
  6575. }
  6576. // winfo — Return window-related information
  6577. //
  6578. // # Description
  6579. //
  6580. // Returns a decimal string giving window's width in pixels. When a window is
  6581. // first created its width will be 1 pixel; the width will eventually be
  6582. // changed by a geometry manager to fulfil the window's needs. If you need the
  6583. // true width immediately after creating a widget, invoke update to force the
  6584. // geometry manager to arrange it, or use winfo reqwidth to get the window's
  6585. // requested width instead of its actual width.
  6586. //
  6587. // More information might be available at the [Tcl/Tk winfo] page.
  6588. //
  6589. // [Tcl/Tk winfo]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/winfo.html
  6590. func WinfoWidth(w *Window) string {
  6591. return evalErr(fmt.Sprintf("winfo width %s", w))
  6592. }
  6593. // tooltip — Tooltip management
  6594. //
  6595. // # Description
  6596. //
  6597. // Prevents the specified widgets from showing tooltips. pattern is a glob
  6598. // pattern and defaults to matching all widgets.
  6599. //
  6600. // More information might be available at the [Tklib tooltip] page.
  6601. //
  6602. // [Tklib tooltip]: https://core.tcl-lang.org/tklib/doc/trunk/embedded/md/tklib/files/modules/tooltip/tooltip.md
  6603. func TooltipClear(pattern string) {
  6604. s := ""
  6605. if pattern != "" {
  6606. s = tclSafeString(pattern)
  6607. }
  6608. evalErr(fmt.Sprintf("tooltip::tooltip clear %s", s))
  6609. }
  6610. // tooltip — Tooltip management
  6611. //
  6612. // # Description
  6613. //
  6614. // Queries or modifies the configuration options of the tooltip. The supported
  6615. // options are -backgroud, -foreground and -font. If one option is specified with
  6616. // no value, returns the value of that option. Otherwise, sets the given
  6617. // options to the corresponding values.
  6618. //
  6619. // More information might be available at the [Tklib tooltip] page.
  6620. //
  6621. // [Tklib tooltip]: https://core.tcl-lang.org/tklib/doc/trunk/embedded/md/tklib/files/modules/tooltip/tooltip.md
  6622. func TooltipConfigure(options ...any) string {
  6623. return evalErr(fmt.Sprintf("tooltip::tooltip configure %s", collectAny(options)))
  6624. }
  6625. // tooltip — Tooltip management
  6626. //
  6627. // # Description
  6628. //
  6629. // Query or set the hover delay. This is the interval that the pointer must
  6630. // remain over the widget before the tooltip is displayed. The delay is
  6631. // specified in milliseconds and must be greater than or equal to 50 ms. With
  6632. // a negative argument the current delay is returned.
  6633. //
  6634. // More information might be available at the [Tklib tooltip] page.
  6635. //
  6636. // [Tklib tooltip]: https://core.tcl-lang.org/tklib/doc/trunk/embedded/md/tklib/files/modules/tooltip/tooltip.md
  6637. func TooltipDelay(delay time.Duration) string {
  6638. s := ""
  6639. if delay >= 0 {
  6640. s = optionString(delay)
  6641. }
  6642. return evalErr(fmt.Sprintf("tooltip::tooltip delay %s", s))
  6643. }
  6644. // tooltip — Tooltip management
  6645. //
  6646. // # Description
  6647. //
  6648. // Enable or disable fading of the tooltip. The fading is enabled by default on
  6649. // Win32 and Aqua. The tooltip will fade away on Leave events instead
  6650. // disappearing.
  6651. //
  6652. // More information might be available at the [Tklib tooltip] page.
  6653. //
  6654. // [Tklib tooltip]: https://core.tcl-lang.org/tklib/doc/trunk/embedded/md/tklib/files/modules/tooltip/tooltip.md
  6655. func TooltipFade(v bool) string {
  6656. return evalErr(fmt.Sprintf("tooltip::tooltip fade %v", v))
  6657. }
  6658. // tooltip — Tooltip management
  6659. //
  6660. // # Description
  6661. //
  6662. // # Disable all tooltips
  6663. //
  6664. // More information might be available at the [Tklib tooltip] page.
  6665. //
  6666. // [Tklib tooltip]: https://core.tcl-lang.org/tklib/doc/trunk/embedded/md/tklib/files/modules/tooltip/tooltip.md
  6667. func TooltipOff(v bool) string {
  6668. return evalErr("tooltip::tooltip off")
  6669. }
  6670. // tooltip — Tooltip management
  6671. //
  6672. // # Description
  6673. //
  6674. // Enables tooltips for defined widgets.
  6675. //
  6676. // More information might be available at the [Tklib tooltip] page.
  6677. //
  6678. // [Tklib tooltip]: https://core.tcl-lang.org/tklib/doc/trunk/embedded/md/tklib/files/modules/tooltip/tooltip.md
  6679. func TooltipOn(v bool) string {
  6680. return evalErr("tooltip::tooltip on")
  6681. }
  6682. // tooltip — Tooltip management
  6683. //
  6684. // # Description
  6685. //
  6686. // This command arranges for widget 'w' to display a tooltip with a
  6687. // message.
  6688. //
  6689. // If the specified widget is a menu, canvas, listbox, ttk::treeview,
  6690. // ttk::notebook or text widget then additional options are used to tie the
  6691. // tooltip to specific menu, canvas or listbox items, ttk::treeview items or
  6692. // column headings, ttk::notebook tabs, or text widget tags.
  6693. //
  6694. // - [Heading] columnId: This option is used to set a tooltip for a
  6695. // ttk::treeview column heading. The column does not need to already exist.
  6696. // You should not use the same identifiers for columns and items in a widget
  6697. // for which you are using tooltips as their tooltips will be mixed. The
  6698. // widget must be a ttk::treeview widget.
  6699. //
  6700. // - [Image] image: The specified (photo) image will be displayed to the left
  6701. // of the primary tooltip message.
  6702. //
  6703. // - [Index] index: This option is used to set a tooltip on a menu item. The
  6704. // index may be either the entry index or the entry label. The widget must be
  6705. // a menu widget but the entries do not have to exist when the tooltip is
  6706. // set.
  6707. //
  6708. // - [Info] info: The specified info text will be displayed as additional
  6709. // information below the primary tooltip message.
  6710. //
  6711. // - [Items] items: This option is used to set a tooltip for canvas, listbox
  6712. // or ttk::treview items. For the canvas widget, the item must already be
  6713. // present in the canvas and will be found with a find withtag lookup. For
  6714. // listbox and ttk::treview widgets the item(s) may be created later but the
  6715. // programmer is responsible for managing the link between the listbox or
  6716. // ttk::treview item index and the corresponding tooltip. If the listbox or
  6717. // ttk::treview items are re-ordered, the tooltips will need amending.
  6718. //
  6719. // If the widget is not a canvas, listbox or ttk::treview then an error is
  6720. // raised.
  6721. //
  6722. // - [Tab] tabId: The -tab option can be used to set a tooltip for a
  6723. // ttk::notebook tab. The tab should already be present when this command is
  6724. // called, or an error will be returned. The widget must be a ttk::notebook
  6725. // widget.
  6726. //
  6727. // - [Tag] name: The -tag option can be used to set a tooltip for a text
  6728. // widget tag. The tag should already be present when this command is called,
  6729. // or an error will be returned. The widget must be a text widget.
  6730. //
  6731. // - "--": The -- option marks the end of options. The argument following
  6732. // this one will be treated as message even if it starts with a -.
  6733. //
  6734. // Tooltip returns 'w'.
  6735. //
  6736. // More information might be available at the [Tklib tooltip] page.
  6737. //
  6738. // [Tklib tooltip]: https://core.tcl-lang.org/tklib/doc/trunk/embedded/md/tklib/files/modules/tooltip/tooltip.md
  6739. func Tooltip(w Widget, options ...any) (r Widget) {
  6740. evalErr(fmt.Sprintf("tooltip::tooltip %s %s", w, collectAny(options...)))
  6741. return w
  6742. }
  6743. // Heading option.
  6744. //
  6745. // Known uses:
  6746. // - [Tooltip] (command specific)
  6747. func Heading(columnId string) Opt {
  6748. return rawOption(fmt.Sprintf(`-heading %s`, optionString(columnId)))
  6749. }
  6750. // Index option.
  6751. //
  6752. // Known uses:
  6753. // - [Tooltip] (command specific)
  6754. func Index(index any) Opt {
  6755. return rawOption(fmt.Sprintf(`-index %s`, optionString(index)))
  6756. }
  6757. // Info option.
  6758. //
  6759. // Known uses:
  6760. // - [Tooltip] (command specific)
  6761. func Info(info string) Opt {
  6762. return rawOption(fmt.Sprintf(`-info %s`, optionString(info)))
  6763. }
  6764. // Items option.
  6765. //
  6766. // Known uses:
  6767. // - [Tooltip] (command specific)
  6768. func Items(items ...any) Opt {
  6769. return rawOption(fmt.Sprintf(`-items %s`, collectAny(items...)))
  6770. }
  6771. // Tab option.
  6772. //
  6773. // Known uses:
  6774. // - [Tooltip] (command specific)
  6775. func Tab(tabId any) Opt {
  6776. return rawOption(fmt.Sprintf(`-tab %s`, collectAny(tabId)))
  6777. }
  6778. // Tag option.
  6779. //
  6780. // Known uses:
  6781. // - [Tooltip] (command specific)
  6782. // - [TextWidget] (command specific)
  6783. func Tag(name string) Opt {
  6784. return rawOption(fmt.Sprintf(`-tag %s`, optionString(name)))
  6785. }
  6786. // ttk::combobox — text field with popdown selection list
  6787. //
  6788. // # Description
  6789. //
  6790. // If newIndex is supplied, sets the combobox value to the element at position
  6791. // newIndex in the list of -values (in addition to integers, the end index is
  6792. // supported and indicates the last element of the list, moreover the same
  6793. // simple interpretation as for the command string index is supported, with
  6794. // simple integer index arithmetic and indexing relative to end). Otherwise,
  6795. // returns the index of the current value in the list of -values or {} if the
  6796. // current value does not appear in the list.
  6797. //
  6798. // More information might be available at the [Tcl/Tk combobox] page.
  6799. //
  6800. // [Tcl/Tk combobox]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_combobox.html
  6801. func (w *TComboboxWidget) Current(newIndex any) (r string) {
  6802. var arg string
  6803. if newIndex != nil {
  6804. arg = tclSafeString(fmt.Sprint(newIndex))
  6805. }
  6806. return evalErr(fmt.Sprintf("%s current %s", w, arg))
  6807. }
  6808. // ttk::treeview — hierarchical multicolumn data display widget
  6809. //
  6810. // # Description
  6811. //
  6812. // Returns the integer index of item within its parent's list of children or -1
  6813. // otherwise.
  6814. //
  6815. // More information might be available at the [Tcl/Tk treeview] page.
  6816. //
  6817. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  6818. func (w *TTreeviewWidget) Index(item any) (r int) {
  6819. s := evalErr(fmt.Sprintf("%s index %s", w, tclSafeString(fmt.Sprint(item))))
  6820. if n, err := strconv.ParseInt(s, 10, 32); err == nil {
  6821. return int(n)
  6822. }
  6823. return -1
  6824. }
  6825. // ttk::treeview — hierarchical multicolumn data display widget
  6826. //
  6827. // # Description
  6828. //
  6829. // If newchildren is not specified, returns the list of children belonging to
  6830. // item.
  6831. //
  6832. // If newchildren is specified, replaces item's child list with newchildren.
  6833. // Items in the old child list not present in the new child list are detached
  6834. // from the tree. None of the items in newchildren may be an ancestor of item.
  6835. //
  6836. // More information might be available at the [Tcl/Tk treeview] page.
  6837. //
  6838. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  6839. func (w *TTreeviewWidget) Children(item any, newChildren ...any) (r []string) {
  6840. switch {
  6841. case len(newChildren) == 0:
  6842. return parseList(evalErr(fmt.Sprintf("%s children %s", w, tclSafeString(fmt.Sprint(item)))))
  6843. default:
  6844. return parseList(evalErr(fmt.Sprintf("%s children %s {%s}", w, tclSafeString(fmt.Sprint(item)), tclSafeList(flat(newChildren...)))))
  6845. }
  6846. }
  6847. // ttk::treeview — hierarchical multicolumn data display widget
  6848. //
  6849. // # Description
  6850. //
  6851. // Returns one of:
  6852. //
  6853. // - heading
  6854. //
  6855. // Tree heading area; use [pathname identify column x y] to determine the
  6856. // heading number.
  6857. //
  6858. // - separator
  6859. //
  6860. // Space between two column headings; [pathname identify column x y] will
  6861. // return the display column identifier of the heading to left of the
  6862. // separator.
  6863. //
  6864. // - tree
  6865. //
  6866. // The tree area.
  6867. //
  6868. // - cell
  6869. //
  6870. // A data cell.
  6871. //
  6872. // More information might be available at the [Tcl/Tk treeview] page.
  6873. //
  6874. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  6875. func (w *TTreeviewWidget) IdentifyRegion(x, y int) (r string) {
  6876. return evalErr(fmt.Sprintf("%s identify region %v %v", w, x, y))
  6877. }
  6878. // ttk::treeview — hierarchical multicolumn data display widget
  6879. //
  6880. // # Description
  6881. //
  6882. // Returns the item ID of the item at position x y.
  6883. //
  6884. // More information might be available at the [Tcl/Tk treeview] page.
  6885. //
  6886. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  6887. func (w *TTreeviewWidget) IdentifyItem(x, y int) (r string) {
  6888. return evalErr(fmt.Sprintf("%s identify item %v %v", w, x, y))
  6889. }
  6890. // ttk::treeview — hierarchical multicolumn data display widget
  6891. //
  6892. // # Description
  6893. //
  6894. // Returns the display column identifier of the cell at position x. The tree
  6895. // column has ID #0.
  6896. //
  6897. // More information might be available at the [Tcl/Tk treeview] page.
  6898. //
  6899. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  6900. func (w *TTreeviewWidget) IdentifyColumn(x, y int) (r string) {
  6901. return evalErr(fmt.Sprintf("%s identify column %v %v", w, x, y))
  6902. }
  6903. // ttk::treeview — hierarchical multicolumn data display widget
  6904. //
  6905. // # Description
  6906. //
  6907. // Returns the cell identifier of the cell at position x, y. A cell identifier
  6908. // is a list of item ID and column ID.
  6909. //
  6910. // More information might be available at the [Tcl/Tk treeview] page.
  6911. //
  6912. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  6913. func (w *TTreeviewWidget) IdentifyCell(x, y int) (r []string) {
  6914. return parseList(evalErr(fmt.Sprintf("%s identify cell %v %v", w, x, y)))
  6915. }
  6916. // ttk::treeview — hierarchical multicolumn data display widget
  6917. //
  6918. // # Description
  6919. //
  6920. // Returns the element at position x, y.
  6921. //
  6922. // More information might be available at the [Tcl/Tk treeview] page.
  6923. //
  6924. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  6925. func (w *TTreeviewWidget) IdentifyElement(x, y int) (r string) {
  6926. return evalErr(fmt.Sprintf("%s identify element %v %v", w, x, y))
  6927. }
  6928. // ttk::treeview — hierarchical multicolumn data display widget
  6929. //
  6930. // # Description
  6931. //
  6932. // Deletes each of the items in itemList and all of their descendants. The root
  6933. // item may not be deleted. See also: detach.
  6934. //
  6935. // More information might be available at the [Tcl/Tk treeview] page.
  6936. //
  6937. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  6938. func (w *TTreeviewWidget) Delete(itemList ...any) {
  6939. itemList = flat(itemList...)
  6940. if len(itemList) == 0 {
  6941. return
  6942. }
  6943. evalErr(fmt.Sprintf("%s delete {%v}", w, tclSafeList(itemList...)))
  6944. }
  6945. func flat(list ...any) (r []any) {
  6946. for _, v := range list {
  6947. switch x := v.(type) {
  6948. case []string:
  6949. for _, v := range x {
  6950. r = append(r, v)
  6951. }
  6952. case []any:
  6953. for _, v := range x {
  6954. r = append(r, flat(v))
  6955. }
  6956. default:
  6957. r = append(r, v)
  6958. }
  6959. }
  6960. return r
  6961. }
  6962. // ttk::treeview — hierarchical multicolumn data display widget
  6963. //
  6964. // # Description
  6965. //
  6966. // Returns the ID of the parent of item, or "" if item is at the top level of
  6967. // the hierarchy.
  6968. //
  6969. // More information might be available at the [Tcl/Tk treeview] page.
  6970. //
  6971. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  6972. func (w *TTreeviewWidget) Parent(item any) (r string) {
  6973. if r = evalErr(fmt.Sprintf("%s parent %s", w, tclSafeString(fmt.Sprint(item)))); r == "{}" {
  6974. r = ""
  6975. }
  6976. return r
  6977. }
  6978. // ttk::treeview — hierarchical multicolumn data display widget
  6979. //
  6980. // # Description
  6981. //
  6982. // Query or modify the options for the specified column. If no -option is
  6983. // specified, returns a dictionary of option/value pairs. If a single -option
  6984. // is specified, returns the value of that option. Otherwise, the options are
  6985. // updated with the specified values. The following options may be set on each
  6986. // column:
  6987. //
  6988. // - id name:
  6989. // The column name. This is a read-only option. For example, [$pathname
  6990. // column #n -id] returns the data column associated with display column n.
  6991. // The tree column has -id #0.
  6992. // - anchor anchor:
  6993. // Specifies how the text in this column should be aligned with respect to
  6994. // the cell. Anchor is one of n, ne, e, se, s, sw, w, nw, or center.
  6995. // - minwidth minwidth:
  6996. // The minimum width of the column in pixels. The treeview widget will not
  6997. // make the column any smaller than -minwidth when the widget is resized or
  6998. // the user drags a heading column separator. Default is 20 pixels.
  6999. // - separator boolean:
  7000. // Specifies whether or not a column separator should be drawn to the right
  7001. // of the column. Default is false.
  7002. // - stretch boolean:
  7003. // Specifies whether or not the column width should be adjusted when the
  7004. // widget is resized or the user drags a heading column separator. Boolean
  7005. // may have any of the forms accepted by Tcl_GetBoolean. By default columns
  7006. // are stretchable.
  7007. // -width width:
  7008. // The width of the column in pixels. Default is 200 pixels. The specified
  7009. // column width may be changed by Tk in order to honor -stretch and/or
  7010. // -minwidth, or when the widget is resized or the user drags a heading
  7011. // column separator.
  7012. //
  7013. // Use pathname "#0" to configure the tree column.
  7014. //
  7015. // More information might be available at the [Tcl/Tk treeview] page.
  7016. //
  7017. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  7018. func (w *TTreeviewWidget) Column(column any, options ...Opt) (r string) {
  7019. return evalErr(fmt.Sprintf("%s column %s %s", w, tclSafeString(fmt.Sprint(column)), collect(options...)))
  7020. }
  7021. // Separator option.
  7022. //
  7023. // Known uses:
  7024. // - [TTreeviewWidget] (command specific)
  7025. //
  7026. // More information might be available at the [Tcl/Tk treeview] page.
  7027. //
  7028. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  7029. func Separator(val any) Opt {
  7030. return rawOption(fmt.Sprintf(`-separator %v`, optionString(val)))
  7031. }
  7032. // ttk::treeview — hierarchical multicolumn data display widget
  7033. //
  7034. // # Description
  7035. //
  7036. // Query or modify the heading options for the specified column. Valid options
  7037. // are:
  7038. //
  7039. // - text text:
  7040. // The text to display in the column heading.
  7041. // - image imageName:
  7042. // Specifies an image to display to the right of the column heading.
  7043. // - anchor anchor:
  7044. // Specifies how the heading text should be aligned. One of the standard Tk anchor values.
  7045. // - command script:
  7046. // A script to evaluate when the heading label is pressed.
  7047. //
  7048. // Use pathname heading "#0" to configure the tree column heading.
  7049. //
  7050. // More information might be available at the [Tcl/Tk treeview] page.
  7051. //
  7052. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  7053. func (w *TTreeviewWidget) Heading(column any, options ...Opt) (r string) {
  7054. return evalErr(fmt.Sprintf("%s heading %s %s", w, tclSafeString(fmt.Sprint(column)), collect(options...)))
  7055. }
  7056. // ttk::treeview — hierarchical multicolumn data display widget
  7057. //
  7058. // # Description
  7059. //
  7060. // Creates a new item. parent is the item ID of the parent item, or the empty
  7061. // string {} to create a new top-level item. index is an integer, or the value
  7062. // end, specifying where in the list of parent's children to insert the new
  7063. // item. If index is negative or zero, the new node is inserted at the
  7064. // beginning; if index is greater than or equal to the current number of
  7065. // children, it is inserted at the end. If -id is specified, it is used as the
  7066. // item identifier; id must not already exist in the tree. Otherwise, a new
  7067. // unique identifier is generated.
  7068. //
  7069. // Insert returns the item identifier of the newly created item. See
  7070. // ITEM OPTIONS for the list of available options.
  7071. //
  7072. // More information might be available at the [Tcl/Tk treeview] page.
  7073. //
  7074. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  7075. func (w *TTreeviewWidget) Insert(parent, index any, options ...Opt) (r string) {
  7076. return evalErr(fmt.Sprintf("%s insert %s %s %s", w, tclSafeString(fmt.Sprint(parent)), tclSafeString(fmt.Sprint(index)), collect(options...)))
  7077. }
  7078. // Id option.
  7079. //
  7080. // Known uses:
  7081. // - [TTreeviewWidget] (command specific)
  7082. //
  7083. // More information might be available at the [Tcl/Tk treeview] page.
  7084. //
  7085. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  7086. func Id(val any) Opt {
  7087. return rawOption(fmt.Sprintf(`-id %s`, optionString(val)))
  7088. }
  7089. // Open option.
  7090. //
  7091. // Known uses:
  7092. // - [TTreeviewWidget] (command specific)
  7093. //
  7094. // More information might be available at the [Tcl/Tk treeview] page.
  7095. //
  7096. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  7097. func Open(val bool) Opt {
  7098. return rawOption(fmt.Sprintf(`-open %v`, val))
  7099. }
  7100. // ttk::treeview — hierarchical multicolumn data display widget
  7101. //
  7102. // # Description
  7103. //
  7104. // Query or modify the options for the specified item. If no -option is
  7105. // specified, returns a dictionary of option/value pairs. If a single -option
  7106. // is specified, returns the value of that option. Otherwise, the item's
  7107. // options are updated with the specified values. See ITEM OPTIONS for the list
  7108. // of available options. pathname move item parent index
  7109. //
  7110. // More information might be available at the [Tcl/Tk treeview] page.
  7111. //
  7112. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  7113. func (w *TTreeviewWidget) Item(item any, options ...any) (r string) {
  7114. if len(options) == 1 {
  7115. if s := funcToTclOption(options[0]); s != "" {
  7116. return evalErr(fmt.Sprintf("%s item %s %s", w, tclSafeString(fmt.Sprint(item)), s))
  7117. }
  7118. }
  7119. return evalErr(fmt.Sprintf("%s item %s %s", w, tclSafeString(fmt.Sprint(item)), collectAny(options...)))
  7120. }
  7121. // ttk::treeview — hierarchical multicolumn data display widget
  7122. //
  7123. // # Description
  7124. //
  7125. // Adds the specified tag to each of the listed items. If tag is already
  7126. // present for a particular item, then the -tags for that item are unchanged.
  7127. //
  7128. // More information might be available at the [Tcl/Tk treeview] page.
  7129. //
  7130. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  7131. func (w *TTreeviewWidget) TagAdd(tag string, items ...any) {
  7132. evalErr(fmt.Sprintf("%s tag add %s %s", w, tclSafeString(tag), collectAny(items...)))
  7133. }
  7134. // ttk::treeview — hierarchical multicolumn data display widget
  7135. //
  7136. // # Description
  7137. //
  7138. // If item is specified, sets the focus item to item. Otherwise, returns the
  7139. // current focus item, or {} if there is none.
  7140. //
  7141. // More information might be available at the [Tcl/Tk treeview] page.
  7142. //
  7143. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  7144. func (w *TTreeviewWidget) Focus(item ...any) (r string) {
  7145. switch len(item) {
  7146. case 0:
  7147. return evalErr(fmt.Sprintf("%s focus", w))
  7148. default:
  7149. return evalErr(fmt.Sprintf("%s focus %s", w, tclSafeString(fmt.Sprint(item[0]))))
  7150. }
  7151. }
  7152. // ttk::treeview — hierarchical multicolumn data display widget
  7153. //
  7154. // # Description
  7155. //
  7156. // Query or modify the options for the specified tagName. If one or more
  7157. // option/value pairs are specified, sets the value of those options for the
  7158. // specified tag. If a single option is specified, returns the value of that
  7159. // option (or the empty string if the option has not been specified for
  7160. // tagName). With no additional arguments, returns a dictionary of the option
  7161. // settings for tagName. See TAG OPTIONS for the list of available options.
  7162. //
  7163. // More information might be available at the [Tcl/Tk treeview] page.
  7164. //
  7165. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  7166. func (w *TTreeviewWidget) TagConfigure(tag string, options ...any) (r string) {
  7167. if len(options) == 1 {
  7168. if s := funcToTclOption(options[0]); s != "" {
  7169. return evalErr(fmt.Sprintf("%s tag configure %s %s", w, tclSafeString(fmt.Sprint(tag)), s))
  7170. }
  7171. }
  7172. return evalErr(fmt.Sprintf("%s tag configure %s %s", w, tclSafeString(tag), collectAny(options...)))
  7173. }
  7174. // ttk::treeview — hierarchical multicolumn data display widget
  7175. //
  7176. // # Description
  7177. //
  7178. // Manages item selection. Item selection is independent from cell selection
  7179. // handled by the cellselection command. If selop is not specified, returns the
  7180. // list of selected items. Otherwise, selop is one of the following:
  7181. //
  7182. // - set itemList:
  7183. // itemList becomes the new selection.
  7184. // - add itemList:
  7185. // Add itemList to the selection.
  7186. // - remove itemList:
  7187. // Remove itemList from the selection.
  7188. // - toggle itemList:
  7189. // Toggle the selection state of each item in itemList.
  7190. //
  7191. // More information might be available at the [Tcl/Tk treeview] page.
  7192. //
  7193. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  7194. func (w *TTreeviewWidget) Selection(selop string, itemList ...any) (r []string) {
  7195. var s string
  7196. if len(itemList) != 0 {
  7197. s = fmt.Sprintf("{%s}", tclSafeList(flat(itemList...)...))
  7198. }
  7199. if selop == "" {
  7200. return parseList(evalErr(fmt.Sprintf("%s selection %s", w, s)))
  7201. }
  7202. evalErr(fmt.Sprintf("%s selection %s %s", w, tclSafeString(fmt.Sprint(selop)), s))
  7203. return nil
  7204. }
  7205. // ttk::treeview — hierarchical multicolumn data display widget
  7206. //
  7207. // # Description
  7208. //
  7209. // Ensure that item is visible: sets all of item's ancestors to -open true, and
  7210. // scrolls the widget if necessary so that item is within the visible portion
  7211. // of the tree.
  7212. //
  7213. // More information might be available at the [Tcl/Tk treeview] page.
  7214. //
  7215. // [Tcl/Tk treeview]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_treeview.html
  7216. func (w *TTreeviewWidget) See(item any) {
  7217. evalErr(fmt.Sprintf("%s see %s", w, tclSafeString(fmt.Sprint(item))))
  7218. }
  7219. // ttk::scale — Create and manipulate a scale widget
  7220. //
  7221. // # Description
  7222. //
  7223. // Get the current value of the -value option, or the value corresponding to
  7224. // the coordinates x,y if they are specified. X and y are pixel coordinates
  7225. // relative to the scale widget origin.
  7226. //
  7227. // More information might be available at the [Tcl/Tk scale] page.
  7228. //
  7229. // [Tcl/Tk scale]: https://tcl.tk/man/tcl9.0/TkCmd/ttk_scale.html
  7230. func (w *TScaleWidget) Get(xy ...any) (r string) {
  7231. arg := ""
  7232. if len(xy) >= 2 {
  7233. arg = fmt.Sprintf("%s %s", tclSafeString(fmt.Sprint(xy[0])), tclSafeString(fmt.Sprint(xy[1])))
  7234. }
  7235. return evalErr(fmt.Sprintf("%s get %s", w, arg))
  7236. }
  7237. // tk_optionMenu — Create an option menubutton and its menu
  7238. //
  7239. // # Description
  7240. //
  7241. // This procedure creates an option menubutton whose name is pathName, plus an
  7242. // associated menu. Together they allow the user to select one of the values
  7243. // given by the value arguments. The current value will be stored in the global
  7244. // variable whose name is given by varName and it will also be displayed as the
  7245. // label in the option menubutton. The user can click on the menubutton to
  7246. // display a menu containing all of the values and thereby select a new value.
  7247. // Once a new value is selected, it will be stored in the variable and appear
  7248. // in the option menubutton. The current value can also be changed by setting
  7249. // the variable.
  7250. //
  7251. // The return value from tk_optionMenu is the name of the menu associated with
  7252. // pathName, so that the caller can change its configuration options or
  7253. // manipulate it in other ways.
  7254. //
  7255. // More information might be available at the [Tcl/Tk option menu] page.
  7256. //
  7257. // [Tcl/Tk option menu]: https://tcl.tk/man/tcl9.0/TkCmd/optionMenu.html
  7258. func OptionMenu(varName *VariableOpt, options ...any) (r *OptionMenuWidget) {
  7259. return App.OptionMenu(varName, options...)
  7260. }
  7261. // tk_optionMenu — Create an option menubutton and its menu
  7262. //
  7263. // The resulting [Widget] is a child of 'w'
  7264. //
  7265. // For details please see [Button]
  7266. func (w *Window) OptionMenu(varName *VariableOpt, options ...any) (r *OptionMenuWidget) {
  7267. r = &OptionMenuWidget{Window: w.newChild0("optionmenu")}
  7268. for i, v := range options {
  7269. if s := fmt.Sprint(v); s == "" {
  7270. options[i] = "{}"
  7271. }
  7272. }
  7273. r.name = evalErr(fmt.Sprintf("tk_optionMenu %s %s %s", r, varName.tclName, tclSafeList(options...)))
  7274. return r
  7275. }
  7276. // OptionMenuWidget represents the Tcl/Tk option menu.
  7277. //
  7278. // More information might be available at the [Tcl/Tk option menu] page.
  7279. //
  7280. // [Tcl/Tk option menu]: https://tcl.tk/man/tcl9.0/TkCmd/optionMenu.html
  7281. type OptionMenuWidget struct {
  7282. *Window
  7283. name string
  7284. }
  7285. // Name returns the menu name of 'w'.
  7286. func (w *OptionMenuWidget) Name() string {
  7287. return w.name
  7288. }
  7289. // grab — Confine pointer and keyboard events to a window sub-tree
  7290. //
  7291. // # Description
  7292. //
  7293. // Same as GrabSet().
  7294. //
  7295. // More information might be available at the [Tcl/Tk grab] page.
  7296. //
  7297. // [Tcl/Tk grab]: https://tcl.tk/man/tcl9.0/TkCmd/grab.html
  7298. func Grab(options ...Opt) {
  7299. GrabSet(options...)
  7300. }
  7301. // grab — Confine pointer and keyboard events to a window sub-tree
  7302. //
  7303. // # Description
  7304. //
  7305. // If window is specified, returns the name of the current grab window in this
  7306. // application for window's display, or an empty string if there is no such
  7307. // window. If window is omitted, the command returns a list whose elements are
  7308. // all of the windows grabbed by this application for all displays, or an empty
  7309. // string if the application has no grabs.
  7310. //
  7311. // More information might be available at the [Tcl/Tk grab] page.
  7312. //
  7313. // [Tcl/Tk grab]: https://tcl.tk/man/tcl9.0/TkCmd/grab.html
  7314. func GrabCurrent(options ...Opt) []string {
  7315. return parseList(evalErr(fmt.Sprintf("grab current %s", collect(options...))))
  7316. }
  7317. // grab — Confine pointer and keyboard events to a window sub-tree
  7318. //
  7319. // # Description
  7320. //
  7321. // Releases the grab on window if there is one, otherwise does nothing.
  7322. //
  7323. // More information might be available at the [Tcl/Tk grab] page.
  7324. //
  7325. // [Tcl/Tk grab]: https://tcl.tk/man/tcl9.0/TkCmd/grab.html
  7326. func GrabRelease(w Opt) {
  7327. evalErr(fmt.Sprintf("grab release %s", w))
  7328. }
  7329. // grab — Confine pointer and keyboard events to a window sub-tree
  7330. //
  7331. // # Description
  7332. //
  7333. // Sets a grab on window. If -global is specified then the grab is global,
  7334. // otherwise it is local. If a grab was already in effect for this application
  7335. // on window's display then it is automatically released. If there is already a
  7336. // grab on window and it has the same global/local form as the requested grab,
  7337. // then the command does nothing.
  7338. //
  7339. // More information might be available at the [Tcl/Tk grab] page.
  7340. //
  7341. // [Tcl/Tk grab]: https://tcl.tk/man/tcl9.0/TkCmd/grab.html
  7342. func GrabSet(options ...Opt) {
  7343. evalErr(fmt.Sprintf("grab set %s", collect(options...)))
  7344. }
  7345. // grab — Confine pointer and keyboard events to a window sub-tree
  7346. //
  7347. // # Description
  7348. //
  7349. // Returns none if no grab is currently set on window, local if a local grab is
  7350. // set on window, and global if a global grab is set.
  7351. //
  7352. // More information might be available at the [Tcl/Tk grab] page.
  7353. //
  7354. // [Tcl/Tk grab]: https://tcl.tk/man/tcl9.0/TkCmd/grab.html
  7355. func GrabStatus(w Opt) string {
  7356. return evalErr(fmt.Sprintf("grab status %s", w))
  7357. }
  7358. // Global option.
  7359. //
  7360. // Known uses:
  7361. // - [Grab] (command specific)
  7362. // - [GrabSet] (command specific)
  7363. func Global() Opt {
  7364. return rawOption("-global")
  7365. }
  7366. // after — Execute a command after a time delay
  7367. //
  7368. // # Description
  7369. //
  7370. // If script is not specified, the command sleeps for duration 'ms' and then
  7371. // returns. Negative duration 'ms' is treated as zero. While the command is
  7372. // sleeping the application does not respond to events.
  7373. //
  7374. // If script is specified, the command returns immediately, but it arranges for
  7375. // a Tcl command to be executed ms milliseconds later as an event handler. The
  7376. // command will be executed exactly once, at the given time. The command will
  7377. // be executed at global level (outside the context of any Tcl procedure). If
  7378. // an error occurs while executing the delayed command then the background
  7379. // error will be reported by the command registered with interp bgerror. The
  7380. // after command returns an identifier that can be used to cancel the delayed
  7381. // command using after cancel. A ms value of 0 (or negative) queues the event
  7382. // immediately with priority over other event types (if not installed withn an
  7383. // event proc, which will wait for next round of events).
  7384. //
  7385. // More information might be available at the [Tcl/Tk after] page.
  7386. //
  7387. // [Tcl/Tk grab]: https://tcl.tk/man/tcl9.0/TkCmd/after.html
  7388. func TclAfter(ms time.Duration, script ...any) string {
  7389. switch {
  7390. case len(script) == 0:
  7391. return evalErr(fmt.Sprintf("after %v", optionString(ms)))
  7392. default:
  7393. return evalErr(fmt.Sprintf("after %v %s", optionString(ms), newEventHandler("", script[0]).optionString(nil)))
  7394. }
  7395. }
  7396. // after — Execute a command after a time delay
  7397. //
  7398. // # Description
  7399. //
  7400. // Cancels the execution of a delayed command that was previously scheduled. Id
  7401. // indicates which command should be canceled; it must have been the return
  7402. // value from a previous after command. If the command given by id has already
  7403. // been executed then the after cancel command has no effect.
  7404. //
  7405. // More information might be available at the [Tcl/Tk after] page.
  7406. //
  7407. // [Tcl/Tk grab]: https://tcl.tk/man/tcl9.0/TkCmd/after.html
  7408. func TclAfterCancel(id string) {
  7409. evalErr(fmt.Sprintf("after cancel %s", tclSafeString(id)))
  7410. }
  7411. // after — Execute a command after a time delay
  7412. //
  7413. // # Description
  7414. //
  7415. // Concatenates the script arguments together with space separators (just as in
  7416. // the concat command), and arranges for the resulting script to be evaluated
  7417. // later as an idle callback. The script will be run exactly once, the next
  7418. // time the event loop is entered and there are no events to process. The
  7419. // command returns an identifier that can be used to cancel the delayed command
  7420. // using after cancel. If an error occurs while executing the script then the
  7421. // background error will be reported by the command registered with interp
  7422. // bgerror.
  7423. //
  7424. // More information might be available at the [Tcl/Tk after] page.
  7425. //
  7426. // [Tcl/Tk grab]: https://tcl.tk/man/tcl9.0/TkCmd/after.html
  7427. func TclAfterIdle(script any) string {
  7428. switch x := script.(type) {
  7429. case nil:
  7430. return ""
  7431. case *eventHandler:
  7432. x.tcl = ""
  7433. return evalErr(fmt.Sprintf("after idle %s", collect(x)))
  7434. default:
  7435. return evalErr(fmt.Sprintf("after idle %s", newEventHandler("", script).optionString(nil)))
  7436. }
  7437. }
  7438. // A helper for ActivateTheme/ActivateExtension.
  7439. func isCalledFromMain() bool {
  7440. pcs := make([]uintptr, 20)
  7441. n := runtime.Callers(3, pcs)
  7442. frames := runtime.CallersFrames(pcs[:n])
  7443. for {
  7444. frame, more := frames.Next()
  7445. if strings.HasPrefix(frame.Function, "main.") {
  7446. return true
  7447. }
  7448. if !more {
  7449. return false
  7450. }
  7451. }
  7452. }
  7453. // Entry — Create and manipulate 'entry' one-line text entry widgets
  7454. //
  7455. // # Description
  7456. //
  7457. // Arrange for the insertion cursor to be displayed just before the character
  7458. // given by index. Returns an empty string.
  7459. //
  7460. // More information might be available at the [Tcl/Tk entry] page.
  7461. //
  7462. // [Tcl/Tk entry]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/entry.html
  7463. func (w *EntryWidget) Icursor(index any) (r string) {
  7464. return evalErr(fmt.Sprintf("%s icursor %s", w, tclSafeString(fmt.Sprint(index))))
  7465. }
  7466. // TEntry — Editable text field widget
  7467. //
  7468. // # Description
  7469. //
  7470. // Arrange for the insertion cursor to be displayed just before the character
  7471. // given by index. Returns an empty string.
  7472. //
  7473. // More information might be available at the [Tcl/Tk ttk_entry] page.
  7474. //
  7475. // [Tcl/Tk ttk_entry]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_entry.html
  7476. func (w *TEntryWidget) Icursor(index any) (r string) {
  7477. return evalErr(fmt.Sprintf("%s icursor %s", w, tclSafeString(fmt.Sprint(index))))
  7478. }
  7479. // listbox — Create and manipulate 'listbox' item list widgets
  7480. //
  7481. // # Description
  7482. //
  7483. // Sets the active element to the one indicated by index. If index is outside
  7484. // the range of elements in the listbox then the closest element is activated.
  7485. // The active element is drawn as specified by -activestyle when the widget has
  7486. // the input focus, and its index may be retrieved with the index active.
  7487. //
  7488. // More information might be available at the [Tcl/Tk listbox] page.
  7489. //
  7490. // [Tcl/Tk listbox]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/listbox.html
  7491. func (w *ListboxWidget) Activate(index any) {
  7492. evalErr(fmt.Sprintf("%s activate %s", w, tclSafeString(fmt.Sprint(index))))
  7493. }
  7494. // listbox — Create and manipulate 'listbox' item list widgets
  7495. //
  7496. // # Description
  7497. //
  7498. // Returns a list containing the numerical indices of all of the elements in the
  7499. // listbox that are currently selected. If there are no elements selected in the
  7500. // listbox then a zero length slice is returned.
  7501. //
  7502. // More information might be available at the [Tcl/Tk listbox] page.
  7503. //
  7504. // [Tcl/Tk listbox]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/listbox.html
  7505. func (w *ListboxWidget) Curselection() (r []int) {
  7506. indicesStrings := parseList(evalErr(fmt.Sprintf("%s curselection", w)))
  7507. indices := make([]int, len(indicesStrings))
  7508. for i, index := range indicesStrings {
  7509. indices[i] = atoi(index)
  7510. }
  7511. return indices
  7512. }
  7513. // listbox — Create and manipulate 'listbox' item list widgets
  7514. //
  7515. // # Description
  7516. //
  7517. // Deletes one or more elements of the listbox. First and last are indices
  7518. // specifying the first and last elements in the range to delete. If last is not
  7519. // specified it defaults to first, i.e. a single element is deleted.
  7520. //
  7521. // More information might be available at the [Tcl/Tk listbox] page.
  7522. //
  7523. // [Tcl/Tk listbox]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/listbox.html
  7524. func (w *ListboxWidget) Delete(first any, last ...any) {
  7525. switch len(last) {
  7526. case 0:
  7527. evalErr(fmt.Sprintf("%s delete %s", w, tclSafeString(fmt.Sprint(first))))
  7528. default:
  7529. evalErr(fmt.Sprintf("%s delete %s %s", w, tclSafeString(fmt.Sprint(first)), tclSafeString(fmt.Sprint(last[0]))))
  7530. }
  7531. }
  7532. // listbox — Create and manipulate 'listbox' item list widgets
  7533. //
  7534. // # Description
  7535. //
  7536. // If last is omitted, returns the contents of the listbox element indicated by
  7537. // first, or an empty string if first refers to a non-existent element. If last
  7538. // is specified, the command returns a list whose elements are all of the
  7539. // listbox elements between first and last, inclusive. Both first and last may
  7540. // have any of the standard forms for indices.
  7541. //
  7542. // More information might be available at the [Tcl/Tk listbox] page.
  7543. //
  7544. // [Tcl/Tk listbox]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/listbox.html
  7545. func (w *ListboxWidget) Get(first any, last ...any) (r []string) {
  7546. switch len(last) {
  7547. case 0:
  7548. return []string{evalErr(fmt.Sprintf("%s get %s", w, tclSafeString(fmt.Sprint(first))))}
  7549. default:
  7550. return parseList(evalErr(fmt.Sprintf("%s get %s %s", w, tclSafeString(fmt.Sprint(first)), tclSafeString(fmt.Sprint(last[0])))))
  7551. }
  7552. }
  7553. // listbox — Create and manipulate 'listbox' item list widgets
  7554. //
  7555. // # Description
  7556. //
  7557. // Returns the integer index value that corresponds to index. If index is end
  7558. // the return value is a count of the number of elements in the listbox
  7559. // (not the index of the last element).
  7560. //
  7561. // More information might be available at the [Tcl/Tk listbox] page.
  7562. //
  7563. // [Tcl/Tk listbox]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/listbox.html
  7564. func (w *ListboxWidget) Index(index any) {
  7565. evalErr(fmt.Sprintf("%s index %s", w, tclSafeString(fmt.Sprint(index))))
  7566. }
  7567. // listbox — Create and manipulate 'listbox' item list widgets
  7568. //
  7569. // # Description
  7570. //
  7571. // Inserts zero or more new elements in the list just before the element given
  7572. // by index. If index is specified as end then the new elements are added to
  7573. // the end of the list.
  7574. //
  7575. // More information might be available at the [Tcl/Tk listbox] page.
  7576. //
  7577. // [Tcl/Tk listbox]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/listbox.html
  7578. func (w *ListboxWidget) Insert(index any, elements ...any) {
  7579. evalErr(fmt.Sprintf("%s insert %s %s", w, tclSafeString(fmt.Sprint(index)), tclSafeList(elements...)))
  7580. }
  7581. // listbox — Create and manipulate 'listbox' item list widgets
  7582. //
  7583. // # Description
  7584. //
  7585. // Given a y-coordinate within the listbox window, this command returns the index
  7586. // of the (visible) listbox element nearest to that y-coordinate.
  7587. //
  7588. // More information might be available at the [Tcl/Tk listbox] page.
  7589. //
  7590. // [Tcl/Tk listbox]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/listbox.html
  7591. func (w *ListboxWidget) Nearest(y any) int {
  7592. return atoi(evalErr(fmt.Sprintf("%s nearest %s", w, tclSafeString(fmt.Sprint(y)))))
  7593. }
  7594. // listbox — Create and manipulate 'listbox' item list widgets
  7595. //
  7596. // # Description
  7597. //
  7598. // Adjust the view in the listbox so that the element given by index is visible.
  7599. // If the element is already visible then the command has no effect; if the
  7600. // element is near one edge of the window then the listbox scrolls to bring
  7601. // the element into view at the edge; otherwise the listbox scrolls to center
  7602. // the element.
  7603. //
  7604. // More information might be available at the [Tcl/Tk listbox] page.
  7605. //
  7606. // [Tcl/Tk listbox]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/listbox.html
  7607. func (w *ListboxWidget) See(index any) {
  7608. evalErr(fmt.Sprintf("%s see %s", w, tclSafeString(fmt.Sprint(index))))
  7609. }
  7610. // listbox — Create and manipulate 'listbox' item list widgets
  7611. //
  7612. // # Description
  7613. //
  7614. // Sets the selection anchor to the element given by index. If index refers
  7615. // to a non-existent element, then the closest element is used. The selection
  7616. // anchor is the end of the selection that is fixed while dragging out a selection
  7617. // with the mouse. The index anchor may be used to refer to the anchor element.
  7618. //
  7619. // More information might be available at the [Tcl/Tk listbox] page.
  7620. //
  7621. // [Tcl/Tk listbox]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/listbox.html
  7622. func (w *ListboxWidget) SelectionAnchor(index any) {
  7623. evalErr(fmt.Sprintf("%s selection anchor %s", w, tclSafeString(fmt.Sprint(index))))
  7624. }
  7625. // listbox — Create and manipulate 'listbox' item list widgets
  7626. //
  7627. // # Description
  7628. //
  7629. // Selects all of the elements in the range between first and last, inclusive,
  7630. // without affecting the selection state of elements outside that range.
  7631. //
  7632. // More information might be available at the [Tcl/Tk listbox] page.
  7633. //
  7634. // [Tcl/Tk listbox]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/listbox.html
  7635. func (w *ListboxWidget) SelectionSet(first any, last ...any) {
  7636. switch len(last) {
  7637. case 0:
  7638. evalErr(fmt.Sprintf("%s selection set %s", w, tclSafeString(fmt.Sprint(first))))
  7639. default:
  7640. evalErr(fmt.Sprintf("%s selection set %s %s", w, tclSafeString(fmt.Sprint(first)), tclSafeString(fmt.Sprint(last[0]))))
  7641. }
  7642. }
  7643. // listbox — Create and manipulate 'listbox' item list widgets
  7644. //
  7645. // # Description
  7646. //
  7647. // Returns 1 if the element indicated by index is currently selected, 0 if it is not.
  7648. //
  7649. // More information might be available at the [Tcl/Tk listbox] page.
  7650. //
  7651. // [Tcl/Tk listbox]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/listbox.html
  7652. func (w *ListboxWidget) SelectionIncludes(index any) bool {
  7653. return evalErr(fmt.Sprintf("%s selection includes %s", w, tclSafeString(fmt.Sprint(index)))) == "1"
  7654. }
  7655. // listbox — Create and manipulate 'listbox' item list widgets
  7656. //
  7657. // # Description
  7658. //
  7659. // If any of the elements between first and last (inclusive) are selected, they
  7660. // are deselected. The selection state is not changed for elements outside this range.
  7661. //
  7662. // More information might be available at the [Tcl/Tk listbox] page.
  7663. //
  7664. // [Tcl/Tk listbox]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/listbox.html
  7665. func (w *ListboxWidget) SelectionClear(first any, last ...any) {
  7666. switch len(last) {
  7667. case 0:
  7668. evalErr(fmt.Sprintf("%s selection clear %s", w, tclSafeString(fmt.Sprint(first))))
  7669. default:
  7670. evalErr(fmt.Sprintf("%s selection clear %s %s", w, tclSafeString(fmt.Sprint(first)), tclSafeString(fmt.Sprint(last[0]))))
  7671. }
  7672. }
  7673. // listbox — Create and manipulate 'listbox' item list widgets
  7674. //
  7675. // # Description
  7676. //
  7677. // Returns a decimal string indicating the total number of elements in the listbox.
  7678. //
  7679. // More information might be available at the [Tcl/Tk listbox] page.
  7680. //
  7681. // [Tcl/Tk listbox]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/listbox.html
  7682. func (w *ListboxWidget) Size() int {
  7683. return atoi(evalErr(fmt.Sprintf("%s size", w)))
  7684. }
  7685. // ttk::progressbar — Provide progress feedback
  7686. //
  7687. // # Description
  7688. //
  7689. // Begin autoincrement mode: schedules a recurring timer event that calls step
  7690. // every interval milliseconds. If omitted, interval defaults to 50
  7691. // milliseconds (20 steps/second).
  7692. //
  7693. // More information might be available at the [Tcl/Tk progressbar] page.
  7694. //
  7695. // [Tcl/Tk progressbar]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_progressbar.html
  7696. func (w *TProgressbarWidget) Start(interval ...time.Duration) {
  7697. s := ""
  7698. if len(interval) != 0 {
  7699. s = fmt.Sprint(int(interval[0] / time.Millisecond))
  7700. }
  7701. evalErr(fmt.Sprintf("%s start %s", w, s))
  7702. }
  7703. // ttk::progressbar — Provide progress feedback
  7704. //
  7705. // # Description
  7706. //
  7707. // Increments the -value by amount. amount defaults to 1.0 if omitted.
  7708. //
  7709. // More information might be available at the [Tcl/Tk progressbar] page.
  7710. //
  7711. // [Tcl/Tk progressbar]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_progressbar.html
  7712. func (w *TProgressbarWidget) Step(amount ...float64) {
  7713. s := ""
  7714. if len(amount) != 0 {
  7715. s = fmt.Sprint(amount[0])
  7716. }
  7717. evalErr(fmt.Sprintf("%s step %s", w, s))
  7718. }
  7719. // ttk::progressbar — Provide progress feedback
  7720. //
  7721. // # Description
  7722. //
  7723. // Stop autoincrement mode: cancels any recurring timer event initiated by
  7724. // pathName start.
  7725. //
  7726. // More information might be available at the [Tcl/Tk progressbar] page.
  7727. //
  7728. // [Tcl/Tk progressbar]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/ttk_progressbar.html
  7729. func (w *TProgressbarWidget) Stop() {
  7730. evalErr(fmt.Sprintf("%s stop", w))
  7731. }
  7732. func goString(p uintptr) string { // Result can be retained.
  7733. if p == 0 {
  7734. return ""
  7735. }
  7736. p0 := p
  7737. var n int
  7738. for ; *(*byte)(unsafe.Pointer(p)) != 0; n++ {
  7739. p++
  7740. }
  7741. if n != 0 {
  7742. return string(unsafe.Slice((*byte)(unsafe.Pointer(p0)), n))
  7743. }
  7744. return ""
  7745. }
  7746. // Values option.
  7747. //
  7748. // Known uses:
  7749. // - [Spinbox] (widget specific)
  7750. // - [TCombobox] (widget specific)
  7751. // - [TSpinbox] (widget specific)
  7752. func Values(val any) Opt {
  7753. switch x := val.(type) {
  7754. case []string:
  7755. return rawOption(fmt.Sprintf(`-values {%s}`, tclSafeStrings(x...)))
  7756. case []any:
  7757. return rawOption(fmt.Sprintf(`-values {%s}`, tclSafeList(x...)))
  7758. default:
  7759. return rawOption(fmt.Sprintf(`-values %s`, optionString(val)))
  7760. }
  7761. }
  7762. // Uniform option.
  7763. //
  7764. // Known uses:
  7765. // - [GridColumnConfigure] (command specific)
  7766. // - [GridRowConfigure] (command specific)
  7767. //
  7768. // More information might be available at the [Tcl/Tk grid] page.
  7769. //
  7770. // [Tcl/Tk grid]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/grid.html#M8
  7771. func Uniform(val any) Opt {
  7772. // Credit: Complex_Signal2842, https://www.reddit.com/r/golang/comments/1jcpp3d/comment/mja2l9s/?context=3
  7773. return rawOption(fmt.Sprintf(`-uniform %s`, tclSafeString(fmt.Sprint(val))))
  7774. }
  7775. // ::tk::mac::OpenApplication
  7776. //
  7777. // # Description
  7778. //
  7779. // If a proc of this name is defined, this proc fill fire when your application is
  7780. // initially opened. It is the default Apple Event handler for kAEOpenApplication, “oapp”.
  7781. //
  7782. // More information might be available at the [Tcl/Tk mac] page.
  7783. //
  7784. // [Tcl/Tk mac]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/tk_mac.html#M8
  7785. func MacOpenApplication(f func()) error {
  7786. r := newEventHandler("", f)
  7787. if _, err := eval(fmt.Sprintf(`proc ::tk::mac::OpenApplication {} {eventDispatcher %v}`, r.id)); err != nil {
  7788. return err
  7789. }
  7790. return nil
  7791. }
  7792. // ::tk::mac::ReopenApplication
  7793. //
  7794. // # Description
  7795. //
  7796. // If a proc of this name is defined it is the default Apple Event handler for kAEReopenApplication, “rapp”,
  7797. // the Apple Event sent when your application is opened when it is already running (e.g. by clicking its icon
  7798. // in the Dock).
  7799. //
  7800. // More information might be available at the [Tcl/Tk mac] page.
  7801. //
  7802. // [Tcl/Tk mac]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/tk_mac.html#M9
  7803. func MacReopenApplication(f func()) error {
  7804. r := newEventHandler("", f)
  7805. if _, err := eval(fmt.Sprintf(`proc ::tk::mac::ReopenApplication {} {eventDispatcher %v}`, r.id)); err != nil {
  7806. return err
  7807. }
  7808. return nil
  7809. }
  7810. // ::tk::mac::OpenDocument
  7811. //
  7812. // # Description
  7813. //
  7814. // If a proc of this name is defined it is the default Apple Event handler for
  7815. // kAEOpenDocuments, “odoc”, the Apple Event sent when your application is asked to
  7816. // open one or more documents (e.g., by drag & drop onto the app or by opening a document
  7817. // of a type associated to the app).
  7818. //
  7819. // More information might be available at the [Tcl/Tk mac] page.
  7820. //
  7821. // [Tcl/Tk mac]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/tk_mac.html#M10
  7822. func MacOpenDocument(f func(string)) error {
  7823. r := newEventHandler("", func(e *Event) { f(e.args[0]) })
  7824. if _, err := eval(fmt.Sprintf(`proc ::tk::mac::OpenDocument {args} {
  7825. foreach f $args {eventDispatcher %v $f}
  7826. }`, r.id)); err != nil {
  7827. return err
  7828. }
  7829. return nil
  7830. }
  7831. // ::tk::mac::Quit
  7832. //
  7833. // # Description
  7834. //
  7835. // If a proc of this name is defined it is the default Apple Event handler for kAEQuitApplication,
  7836. // “quit”, the Apple Event sent when your application is asked to be quit, e.g. via the quit menu
  7837. // item in the application menu, the quit menu item in the Dock menu, or during a
  7838. // logout/restart/shutdown etc. If this is not defined, [exit] is called instead.
  7839. //
  7840. // More information might be available at the [Tcl/Tk mac] page.
  7841. //
  7842. // [exit]: https://www.tcl-lang.org/man/tcl9.0/TclCmd/exit.html
  7843. // [Tcl/Tk mac]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/tk_mac.html#M12
  7844. func MacQuit(f func()) error {
  7845. r := newEventHandler("", f)
  7846. if _, err := eval(fmt.Sprintf(`proc ::tk::mac::Quit {} {eventDispatcher %v}`, r.id)); err != nil {
  7847. return err
  7848. }
  7849. return nil
  7850. }
  7851. // ::tk::mac::OnHide
  7852. //
  7853. // # Description
  7854. //
  7855. // If defined, this is called when your application receives a kEventAppHidden event,
  7856. // e.g. via the hide menu item in the application or Dock menus.
  7857. //
  7858. // More information might be available at the [Tcl/Tk mac] page.
  7859. //
  7860. // [Tcl/Tk mac]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/tk_mac.html#M13
  7861. func MacOnHide(f func()) error {
  7862. r := newEventHandler("", f)
  7863. if _, err := eval(fmt.Sprintf(`proc ::tk::mac::OnHide {} {eventDispatcher %v}`, r.id)); err != nil {
  7864. return err
  7865. }
  7866. return nil
  7867. }
  7868. // ::tk::mac::OnShow
  7869. //
  7870. // # Description
  7871. //
  7872. // If defined, this is called when your application receives a kEventAppShown event,
  7873. // e.g. via the show all menu item in the application menu, or by clicking the Dock icon of a hidden application.
  7874. //
  7875. // More information might be available at the [Tcl/Tk mac] page.
  7876. //
  7877. // [Tcl/Tk mac]: https://www.tcl-lang.org/man/tcl9.0/TkCmd/tk_mac.html#M14
  7878. func MacOnShow(f func()) error {
  7879. r := newEventHandler("", f)
  7880. if _, err := eval(fmt.Sprintf(`proc ::tk::mac::OnShow {} {eventDispatcher %v}`, r.id)); err != nil {
  7881. return err
  7882. }
  7883. return nil
  7884. }