scrn-fld.mklx /size: 36 Kb    last modification: 2021-10-28 13:51
1%D \module
2%D   [       file=scrn-fld,
3%D        version=1997.05.18,
4%D          title=\CONTEXT\ Screen Macros,
5%D       subtitle=Fields,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14%D There is still some leftover code from mkii, where we need to be sparse with hash
15%D entries and so have a somewhat complex setup mechanism. It doesn't pay off to
16%D waste time on improving this because one never knows what happens with widgets
17%D in \PDF; it has a history of dropping features like this. Also, the implementation
18%D of fields fluctuates with versions.
19
20% interaction checking
21
22\writestatus{loading}{ConTeXt Screen Macros / Fields}
23
24\unprotect
25
26\registerctxluafile{scrn-fld}{}
27
28%D In \MKII\ we had to cheat a bit with setups in order not to run out of memory
29%D with thousands of fields, which we happen to need at that time. In \MKIV\ we can
30%D store some data at the \LUA\ end and use a somewhat slower but quite okay
31%D inheritance mechanism. For this reason we now have split definitions, although
32%D the old method is still somewhat supported. The clone and copy commands are
33%D somewhat obsolete for several reasons: we can now use inheritance and autocloning
34%D has been supported for a while. In most cases cloning (especially with check
35%D boxes) the acrobat browser is not stable enough with respect to appearance
36%D handling.
37%D
38%D A fieldcategory is nothing more than a collection of settings.
39%D
40%D \starttyping
41%D \definefieldcategory
42%D   [all-email]
43%D   [height=1cm,
44%D    width=14cm,
45%D    style=sstf]
46%D \stoptyping
47%D
48%D A definition can refer to this category:
49%D
50%D \starttyping
51%D \definefieldbody [email] [type=line,category=all-email,default=pragma@xs4all.nl]
52%D \stoptyping
53%D
54%D A copy of a field is made as follows:
55%D
56%D \starttyping
57%D \definefieldbody [xmail] [email]
58%D \stoptyping
59%D
60%D You can also be more specific:
61%D
62%D \starttyping
63%D \definefieldbody[buttona][type=check,values={one,two}]
64%D \definefieldbody[buttonb][type=check,values={three,four}]
65%D \definefieldbody[buttonc][buttona][values={three,four}]
66%D \stoptyping
67%D
68%D Actually typesetting a field happens this way:
69%D
70%D \starttyping
71%D \fieldbody [Email]
72%D \fieldbody [Email] [width=6cm]
73%D \fieldbody [eMAIL]
74%D \fieldbody [eMAIL] [width=7cm]
75%D
76%D \fieldbody [buttona]
77%D \fieldbody [buttona]
78%D \fieldbody [buttonb]
79%D \fieldbody [buttonb]
80%D \fieldbody [buttonc]
81%D \fieldbody [buttonc]
82%D \stoptyping
83%D
84%D So, you can call up a field many times and quite some parameters can be set.
85%D
86%D Because there are persistent problems with acrobat rendering associated
87%D appearance streams (some messy /MK interferende) we also support native (built-in
88%D dingbat) symbols: check, circle, cross, diamond, square and star.
89%D
90%D \starttyping
91%D \definefield[test1][check]
92%D \definefield[test2][check]
93%D
94%D \fieldbody[test1][width=1em,height=\strutht,depth=\strutdp,symbol=check]
95%D \fieldbody[test1][width=1em,height=\strutht,depth=\strutdp,symbol=circle]
96%D \fieldbody[test2][width=1em,height=\strutht,depth=\strutdp,symbol=square]
97%D \stoptyping
98%D
99%D When submitting a form, we need to tell the driver module that we want \FDF\ or
100%D \HTML.
101
102\installcorenamespace {forms}
103
104\installdirectcommandhandler \??forms {forms}
105
106\appendtoks
107    \clf_setformsmethod{\formsparameter\c!method}%
108\to \everysetupforms
109
110\setupforms
111  [\c!method=XML] % no need for everyjob initialization as this is the default
112
113\mutable\let\currentfieldbackgroundcolor     \empty
114\mutable\let\currentfieldbackgroundcolorvalue\empty
115\mutable\let\currentfieldbodycategory        \empty
116\mutable\let\currentfieldframecolor          \empty
117\mutable\let\currentfieldframecolorvalue     \empty
118\mutable\let\currentfieldlabel               \empty
119\mutable\let\currentfieldstackname           \empty
120
121\appendtoks
122    \iflocation
123      \clf_exportformdata{\formsparameter\c!export}%
124    \fi
125\to \everystoptext
126
127%D We need to initialize symbols in a special way so that they can be used as
128%D rendering for a widget.
129
130\permanent\protected\def\presetfieldsymbols[#list]% slow
131  {\processcommacommand[#list]\scrn_symbols_preset}
132
133\def\scrn_symbols_preset#set%
134  {\processcommalist[#set]\scrn_symbols_preset_indeed}%
135
136\permanent\protected\def\scrn_symbols_preset_indeed#tag%
137  {\doifelseobjectfound{SYM}{#tag}
138     {}
139     {\settightobject{SYM}{#tag}\hbox{\symbol[#tag]}%                        % todo: set this as immediate xform
140      \page_otr_add_special_content{\hskip-\maxdimen\getobject{SYM}{#tag}}}} % and then force it into the file
141
142\aliased\let\dosetfieldsymbol\scrn_symbols_preset_indeed
143
144\permanent\def\dogetfieldsymbol#tag%
145  {\getobject{SYM}{#tag}}
146
147\permanent\protected\def\definedefaultsymbols % used ?
148  {\definesymbol[defaultyes][\mathematics{\times}]%
149   \definesymbol[defaultno] [\mathematics{\cdot }]}
150
151%D Now comes the real code:
152
153\installcorenamespace{fieldcategory}
154\installcorenamespace{fieldbody}
155
156\installcommandhandler \??fieldcategory {fieldcategory} \??fieldcategory
157\installcommandhandler \??fieldbody     {fieldbody}     \??fieldbody
158
159\newbox\b_scrn_field_body
160
161\setupfieldcategory
162  [\c!alternative=\v!normal, % normal clone copy
163   \c!type=\v!line,          % line text ...
164   \c!width=5em,
165   \c!height=1em,
166   \c!depth=\zeropoint,
167   \c!align=\v!flushleft,
168   \c!option=\v!printable, % maybe we need a globaloptions and marge them
169   \c!n=1024]
170
171\def\scrn_field_check_category
172  {\edef\currentfieldbodycategory{\fieldbodyparameter\c!category}%
173   \ifempty\currentfieldbodycategory
174     \letfieldbodyparameter\s!parent\??fieldcategory
175    %\setevalue{\currentfieldbodyhash\s!parent}{\namedfieldcategoryhash\empty}% to WS: not hash !
176   \else
177     \normalexpanded{\setfieldbodyparameter{\s!parent}{\??fieldcategory\currentfieldbodycategory}}%
178    %\setevalue{\currentfieldbodyhash\s!parent}{\namedfieldcategoryhash\currentfieldbodycategory}% to WS: not hash !
179   \fi}
180
181\appendtoks % we cannot use parent .. maybe s!parent has to change
182    \ifempty\currentfieldbodyparent
183        \scrn_field_check_category
184        \clf_definefield
185            name        {\currentfieldbody}%
186            alternative {normal}%
187            type        {\fieldbodyparameter\c!type}%
188            category    {\fieldbodyparameter\c!category}%
189            values      {\fieldbodyparameter\c!values}%
190            default     {\fieldbodyparameter\c!default}%
191        \relax
192    \else
193        \clf_clonefield
194            children    {\currentfieldbody}%
195            alternative {clone}%
196            parent      {\currentfieldbodyparent}%
197            category    {\fieldbodyparameter\c!category}%
198            values      {\fieldbodyparameter\c!values}%
199            default     {\fieldbodyparameter\c!default}%
200        \relax
201    \fi
202\to \everydefinefieldbody
203
204\permanent\tolerant\protected\def\fieldbody[#tag]#spacer[#settings]%
205  {\iflocation
206     \hbox\bgroup
207       \edef\currentfieldbody{#tag}%
208       \setupcurrentfieldbody[#settings]%
209       \scrn_field_body_typeset
210       \box\b_scrn_field_body
211       \egroup
212   \fi}
213
214\def\scrn_field_body_typeset % todo: fieldsymbol (checkfields /MK mess)
215  {\edef\currentfieldframecolor{\fieldbodyparameter\c!fieldframecolor}%
216   \ifempty\currentfieldframecolor\else
217     \getcolorattributevalue\currentfieldframecolor\currentfieldframecolorvalue
218    % == \edef\currentfieldframecolorvalue{\thecolorattribute\currentfieldframecolor}%
219   \fi
220   \edef\currentfieldbackgroundcolor{\fieldbodyparameter\c!fieldbackgroundcolor}%
221   \ifempty\currentfieldbackgroundcolor\else
222     \getcolorattributevalue\currentfieldbackgroundcolor\currentfieldbackgroundcolorvalue
223    % == \edef\currentfieldbackgroundcolorvalue{\thecolorattribute\currentfieldbackgroundcolor}%
224   \fi
225   \usefieldbodystyleandcolor\c!style\c!color
226   \clf_insertfield
227     {\currentfieldbody}%
228     {%
229       title                {\currentfieldbody}
230       width                \dimexpr\fieldbodyparameter\c!width \relax
231       height               \dimexpr\fieldbodyparameter\c!height\relax
232       depth                \dimexpr\fieldbodyparameter\c!depth \relax
233       align                {\fieldbodyparameter\c!align}%
234       length               {\fieldbodyparameter\c!n}%
235       fontstyle            {\fontstyle}%
236       fontalternative      {\fontalternative}%
237       fontsize             {\fontbody}%
238       fontsymbol           {\fieldbodyparameter\c!symbol}%
239       color                {\fieldbodyparameter\c!color}%
240       colorvalue           \c_attr_color
241   \ifempty\currentfieldbackgroundcolor \else
242       backgroundcolor      {\currentfieldbackgroundcolor}%
243       backgroundcolorvalue \numexpr\currentfieldbackgroundcolorvalue\relax
244   \fi
245   \ifempty\currentfieldframecolor \else
246       framecolor           {\currentfieldframecolor}%
247       framecolorvalue      \numexpr\currentfieldframecolorvalue\relax
248   \fi
249       layer                {\fieldbodyparameter\c!fieldlayer}%
250       option               {\fieldbodyparameter\c!option}%
251       clickin              {\fieldbodyparameter\c!clickin}%
252       clickout             {\fieldbodyparameter\c!clickout}%
253       regionin             {\fieldbodyparameter\c!regionin}%
254       regionout            {\fieldbodyparameter\c!regionout}%
255       afterkey             {\fieldbodyparameter\c!afterkey}%
256       format               {\fieldbodyparameter\c!format}%
257       validate             {\fieldbodyparameter\c!validate}%
258       calculate            {\fieldbodyparameter\c!calculate}%
259       focusin              {\fieldbodyparameter\c!focusin}%
260       focusout             {\fieldbodyparameter\c!focusout}%
261       openpage             {\fieldbodyparameter\c!openpage}%
262       closepage            {\fieldbodyparameter\c!closepage}%
263      }%
264    \relax}
265
266%D The sets are used in grouped calculations.
267%D
268%D [name] [set]
269
270\permanent\tolerant\protected\def\definefieldbodyset[#tag]#spacer[#list]%
271  {\clf_definefieldset{#tag}{#list}}
272
273\aliased\let\dodefinefieldset\definefieldbodyset % compatibility
274
275%D A few testing macros (expandable for historic reasons):
276
277\permanent\def\doifelsefieldbody    #tag{\clf_doifelsefield{#tag}}
278\permanent\def\doifelsefieldcategory#tag{\clf_doifelsefieldcategory{#tag}}
279
280\aliased\let\doiffieldbodyelse    \doifelsefieldbody
281\aliased\let\doiffieldcategoryelse\doifelsefieldcategory
282
283\aliased\let\doiffieldelse        \doifelsefieldbody % compatibility / will be dropped
284\aliased\let\doifelsefield        \doifelsefieldbody % compatibility / will be dropped
285
286%D We still support the traditional method of defining fields:
287%D
288%D \starttyping
289%D \definefield [name] [type] [category] [values] [default]
290%D
291%D \definefield [WWWW] [text]  [textsetup]            [default text]
292%D \definefield [XXXX] [push]  [pushsetup]  [yes,no]  [yes]
293%D \definefield [XXXX] [check] [checksetup] [yes,no]  [yes]
294%D \definefield [YYYY] [combo] [combosetup] [a,b,c,d] [b]
295%D \definefield [ZZZZ] [radio] [radiosetup] [W,X,Y,Z] [Y]
296%D
297%D \definesubfield [W]   [subsetup] [p,q]
298%D \definesubfield [X,Y] [subsetup] [p,r]
299%D \definesubfield [Z]   [subsetup] [y,z]
300%D
301%D evt \definemainfield ... wanneer geplaatst voor subs gegeven
302%D
303%D \clonefield [XXXX] [XX,YY] [mysetup]      [on,off]
304%D \clonefield [Z]    [AA,BB] [somesetup]    [true,false]
305%D \clonefield [Z]    [CC,DD] [anothersetup]
306%D
307%D \copyfield [XXXX] [PP,QQ,RR]
308%D \stoptyping
309%D
310%D Keep in mind that you can also use \type {\definefieldbody} to achieve the same.
311
312\permanent\tolerant\protected\def\definefield[#tag]#spacer[#type]#spacer[#category]#spacer[#values]#spacer[#default]%
313  {\definefieldbody[#tag][\c!type=#type,\c!category=#category,\c!values={#values},\c!default={#default}]}
314
315\permanent\tolerant\protected\def\definesubfield[#tag]#spacer[#category]#spacer[#values]%
316  {\definefieldbody[#tag][\c!type=sub,\c!category=#category,\c!values={#values}]}
317
318\permanent\tolerant\protected\def\clonefield[#parent]#spacer[#tag]#spacer[#category]#spacer[#values]%
319  {\definefieldbody[#tag][#parent][\c!category=#category,\c!values={#values}]}
320
321\permanent\tolerant\protected\def\copyfield[#parent]#spacer[#tag]%
322  {\definefieldbody[#tag][#parent]}
323
324\aliased\let\definemainfield\definefield % obsolete !
325
326%D We hook fields into the (viewer based) layering mechanism
327%D (implemented as properties).
328
329\appendtoks
330    \let\currentfieldcategory\empty
331    \doifelse{\interactionparameter\c!fieldlayer}\v!auto
332      {\setupcurrentfieldcategory[\c!fieldlayer=\currentviewerlayer]}%
333      {\setupcurrentfieldcategory[\c!fieldlayer=]}%
334\to \everysetupinteraction
335
336\setupinteraction
337  [\c!fieldlayer=\v!auto] % auto by default
338
339%D The \type {\fieldbody} is the more bare one. One step further goes \type
340%D {\fitfield}, in fact it (now) uses a dedicated instance of framed: \type
341%D {fitfieldframed}.
342%D
343%D \starttyping
344%D \ruledhbox{\fieldbody[Email][height=\strutht,depth=\strutdp,style=normal]}
345%D \ruledhbox{\fitfield[Email][height=\strutht,depth=\strutdp,style=normal]}
346%D \ruledhbox{\fitfield[buttona]}
347%D \stoptyping
348
349\newbox\b_scrn_field_fit_symbol
350
351\defineframed
352  [fitfieldframed]
353  [\c!strut=\v!no,
354   \c!frame=off,
355   \c!offset=\v!overlay,
356   \c!align=]
357
358\permanent\tolerant\protected\def\fitfield[#tag]#spacer[#settings]%
359  {\iflocation
360     \begingroup
361       \setbox\b_scrn_field_fit_symbol\hbox\bgroup
362         \normalexpanded{\symbol[\clf_getdefaultfieldvalue{#tag}]}%
363       \egroup
364       \fitfieldframed
365         {\fieldbody[#tag]
366            [\c!width=\wd\b_scrn_field_fit_symbol,
367             \c!height=\ht\b_scrn_field_fit_symbol,
368             \c!depth=\dp\b_scrn_field_fit_symbol,
369             #settings]}%
370     \endgroup
371   \fi}
372
373%D The traditional field command does some labeling and boxing:
374
375\installcorenamespace{fieldlabel}
376\installcorenamespace{fieldcontent}
377\installcorenamespace{fieldtotal}
378
379\installparameterhandler     \??fieldlabel   {fieldlabelframed}
380\installparameterhandler     \??fieldcontent {fieldcontentframed}
381\installparameterhandler     \??fieldtotal   {fieldtotalframed}
382
383\installparametersethandler  \??fieldcontent {fieldcontentframed}
384
385\installsetuphandler         \??fieldlabel   {fieldlabelframed}
386\installsetuphandler         \??fieldcontent {fieldcontentframed}
387\installsetuphandler         \??fieldtotal   {fieldtotalframed}
388
389\installinheritedframed                      {fieldlabelframed}
390\installinheritedframed                      {fieldcontentframed}
391\installinheritedframed                      {fieldtotalframed}
392
393\setupfieldcontentframed
394  [\c!align=\v!flushleft,
395   \c!strut=\v!no,
396   \s!parent=\??regularframed] % needs checking
397
398\setupfieldcontentframed % independent
399  [\c!alternative=\v!normal,
400   \c!type=\v!line,
401   \c!width=5em,
402   \c!height=\lineheight,
403   \c!depth=\zeropoint,
404   \c!align=\v!flushleft,
405   \c!option=\v!printable,
406   \c!n=1024]
407
408\setupfieldlabelframed
409  [\c!style=,
410   \c!color=,
411   \c!align=\v!flushleft,
412   \s!parent=\??regularframed] % needs checking
413
414\setupfieldtotalframed
415  [%\c!alternative={\v!label,\v!frame,\v!horizontal},
416   \c!strut=\v!no,
417   \c!align=,
418   \s!parent=\??regularframed] % needs checking
419
420% \setupcurrent
421
422\permanent\tolerant\protected\def\setupfield[#tag]#spacer[#variant]#spacer[#totalsettings]#spacer[#labelsettings]#spacer[#fieldsettings]%
423  {\ifarguments\or\or
424     \definefieldcategory[#tag][\s!parent=\??fieldcontent#tag,#variant]%
425     \setupfieldtotalframed  [#tag][\s!parent=\??fieldtotal]%
426     \setupfieldlabelframed  [#tag][\s!parent=\??fieldlabel]%
427     \setupfieldcontentframed[#tag][\s!parent=\??fieldcontent,#variant]%
428   \or
429     \definefieldcategory[#tag][\s!parent=\??fieldcontent#tag,#totalsettings]%
430     \setupfieldtotalframed  [#tag][\s!parent=\??fieldtotal,\c!alternative={#variant}]%
431     \setupfieldlabelframed  [#tag][\s!parent=\??fieldlabel]%
432     \setupfieldcontentframed[#tag][\s!parent=\??fieldcontent,#totalsettings]%
433   \or
434     \definefieldcategory[#tag][\s!parent=\??fieldcontent#tag,#labelsettings]%
435     \setupfieldtotalframed  [#tag][\s!parent=\??fieldtotal,\c!alternative={#variant},#totalsettings]%
436     \setupfieldlabelframed  [#tag][\s!parent=\??fieldlabel]%
437     \setupfieldcontentframed[#tag][\s!parent=\??fieldcontent,#labelsettings]%
438   \or
439     \definefieldcategory[#tag][\s!parent=\??fieldcontent#tag,#fieldsettings]%
440     \setupfieldtotalframed  [#tag][\s!parent=\??fieldtotal,\c!alternative={#variant},#totalsettings]%
441     \setupfieldlabelframed  [#tag][\s!parent=\??fieldlabel,#labelsettings]%
442     \setupfieldcontentframed[#tag][\s!parent=\??fieldcontent,#fieldsettings]%
443   \fi}
444
445\permanent\tolerant\protected\def\setupfields[#variant]#spacer[#totalsettings]#spacer[#labelsettings]#spacer[#fieldsettings]%
446  {\ifarguments\or
447     \setupfieldtotalframed  [#variant]%
448   \or
449     \setupfieldtotalframed  [#variant]%
450     \setupfieldcontentframed[#totalsettings]%
451   \or
452     \setupfieldtotalframed  [#variant]%
453     \setupfieldlabelframed  [#totalsettings]%
454     \setupfieldcontentframed[#labelsettings]%
455   \or
456     \setupfieldtotalframed  [\c!alternative={#variant},#totalsettings]%
457     \setupfieldlabelframed  [#labelsettings]%
458     \setupfieldcontentframed[#fieldsettings]%
459   \fi}
460
461% just to get the chain right for no category:
462
463\definefieldcategory    [][\s!parent=\??fieldcontent]
464%setupfieldtotalframed  [][\s!parent=\??fieldtotal]
465%setupfieldlabelframed  [][\s!parent=\??fieldlabel]
466%setupfieldcontentframed[][\s!parent=\??fieldcontent]
467
468% no longer supported:
469
470% \let\resetfields\relax
471
472\def\scrn_field_load_scripts{\useJSscripts[fld]\glet\scrn_field_load_scripts\relax}
473
474\newconditional\fieldlabelshown
475\newconditional\fieldframeshown
476\newconditional\fieldisvertical
477\newconditional\fieldishorizontal
478
479\mutable\let\currentfieldtotalframed  \empty
480\mutable\let\currentfieldlabelframed  \empty
481\mutable\let\currentfieldcontentframed\empty
482
483\mutable\let\fieldtotalframedparameterhash  \empty % weird that we have to flag this
484\mutable\let\fieldlabelframedparameterhash  \empty % idem
485\mutable\let\fieldcontentframedparameterhash\empty % idem
486
487\permanent\tolerant\protected\def\field[#tag]#spacer[#label]% can be sped up with \setupcurrentfieldtotalframed etc
488  {\iflocation
489     \dontleavehmode
490     \begingroup
491     \scrn_field_load_scripts
492     \edef\currentfieldbody    {#tag}%
493     \edef\currentfieldlabel   {#label}%
494     \edef\currentfieldcategory{\clf_getfieldcategory{#tag}}%
495     \ifempty\currentfieldlabel
496       \let\currentfieldlabel\currentfieldbody
497     \fi
498     \ifempty\currentfieldcategory
499       \setupfieldtotalframed  [\currentfieldbody][\s!parent=\??fieldtotal]%
500       \setupfieldlabelframed  [\currentfieldbody][\s!parent=\??fieldlabel]%
501       \setupfieldcontentframed[\currentfieldbody][\s!parent=\??fieldcontent]%
502       \definefieldcategory    [\currentfieldbody]%
503       \setupfieldbody         [\currentfieldbody][\c!category=\currentfieldbody]%
504       \let\currentfieldcategory\currentfieldbody
505     \fi
506     \let\currentfieldtotalframed  \currentfieldcategory
507     \let\currentfieldlabelframed  \currentfieldcategory
508     \let\currentfieldcontentframed\currentfieldcategory
509     \scrn_field_analyze_setups
510     \ifconditional\fieldframeshown
511       \inheritedfieldtotalframedframed % lower framedoffset
512       \bgroup
513     \else
514       \vbox
515       \bgroup
516     \fi
517     \dontcomplain
518     \ifconditional\fieldlabelshown
519       \scrn_field_set_label_box
520     \fi
521     \scrn_field_set_content_box
522     \ifconditional\fieldlabelshown
523       \ifconditional\fieldisvertical
524         \scrn_field_flush_vertical
525       \else
526         \scrn_field_flush_horizontal
527       \fi
528     \else
529       \scrn_field_flush_content
530     \fi
531     \egroup
532     \endgroup
533   \fi}
534
535% opties: veld, label, kader, vertikaal/horizontaal
536
537\newbox\b_scrn_field_label
538\newbox\b_scrn_field_content
539
540% lower framedoffset
541
542\def\scrn_field_set_label_box
543  {\setbox\b_scrn_field_label\hbox
544      {\reshapeframeboxtrue % else wrong dimensions % still needed?
545       \inheritedfieldlabelframedframed{\currentfieldlabel}}}
546
547% \c!fieldoffset=-\framedoffset,\c!fieldbackgroundcolor=,
548% \hbox{\lower\@@fdfieldoffset\hbox{\typesetfield}}
549
550\def\scrn_field_set_content_box
551  {\setbox\b_scrn_field_content\hbox
552     {\reshapeframeboxtrue % else wrong dimensions (to be checked)
553      \doifnothing{\fieldcontentframedparameter\c!height}
554        {\ifconditional\fieldisvertical
555           \setfieldcontentframedparameter\c!height{6ex}%
556         \orelse\ifconditional\fieldishorizontal
557           \setfieldcontentframedparameter\c!height{\vsize}%
558         \else
559           \setfieldcontentframedparameter\c!height{2cm}%
560         \fi}%
561      \doifnothing{\fieldcontentframedparameter\c!width}
562        {\ifconditional\fieldisvertical
563           \setfieldcontentframedparameter\c!width{\hsize}%
564         \orelse\ifconditional\fieldishorizontal
565           \setfieldcontentframedparameter\c!width{20em}%
566         \else
567           \setfieldcontentframedparameter\c!width{2cm}%
568         \fi}%
569      \inheritedfieldcontentframedframed % lower framedoffset
570        {\fieldbody
571           [\currentfieldbody]
572           [\c!width=\framedwidth,\c!height=\framedheight]}}}
573
574
575\def\scrn_field_flush_vertical
576  {\vbox
577     {\copy\b_scrn_field_label
578      \fieldtotalframedparameter\c!inbetween
579      \copy\b_scrn_field_content}}
580
581\def\scrn_field_flush_horizontal
582   {\hbox
583      {\vbox \ifdim\ht\b_scrn_field_content>\ht\b_scrn_field_label to \ht\b_scrn_field_content \fi
584         {\fieldtotalframedparameter\c!before
585          \copy\b_scrn_field_label
586          \fieldtotalframedparameter\c!after}%
587       \hskip\fieldtotalframedparameter\c!distance
588       \vbox \ifdim\ht\b_scrn_field_label>\ht\b_scrn_field_content to \ht\b_scrn_field_label \fi
589         {\fieldtotalframedparameter\c!before
590          \box\b_scrn_field_content
591          \fieldtotalframedparameter\c!after}}}
592
593\def\scrn_field_flush_content
594  {\box\b_scrn_field_content}
595
596%D todo: replace \processallactionsinset
597
598\def\scrn_field_analyze_setups
599  {\setfalse\fieldlabelshown
600   \setfalse\fieldframeshown
601   \setfalse\fieldishorizontal
602   \setfalse\fieldisvertical
603   \normalexpanded{\processallactionsinset[\fieldtotalframedparameter\c!alternative]}
604     [      \v!reset=>\setfalse\fieldlabelshown
605                      \setfalse\fieldframeshown
606                      \setfalse\fieldishorizontal
607                      \setfalse\fieldisvertical,
608            \v!label=>\settrue\fieldlabelshown,
609            \v!frame=>\settrue\fieldframeshown,
610       \v!horizontal=>\settrue\fieldishorizontal,
611         \v!vertical=>\settrue\fieldisvertical]%
612   \ifconditional\fieldisvertical
613     \setupfieldtotalframed[\c!distance=\zeropoint,\c!inbetween=\vskip\d_framed_local_offset,\c!align=\v!right,\c!width=20em]%
614   \orelse\ifconditional\fieldishorizontal
615     \setupfieldtotalframed[\c!distance=\d_framed_local_offset,\c!inbetween=,\c!align=\c!left,\c!height=10ex]%
616   \else
617     \setupfieldtotalframed[\c!distance=\zeropoint,\c!inbetween=,\c!align=\c!left]%
618   \fi
619   \setupfieldtotalframed[\c!n=,\c!before=,\c!after=\vss,\c!style=,\c!color=]}
620
621%D Common stuff (obsolete)
622
623\newcount\c_scrn_field_system_n
624
625\permanent\def\currentsystemfield{sys::\number\c_scrn_field_system_n}
626
627\permanent\protected\def\nextsystemfield
628  {\global\advance\c_scrn_field_system_n\plusone}
629
630%D \CONTEXT\ had tooltips right from the moment that it supported fields. Due to the
631%D at that moment somewhat limited \PDF\ specification, they were implemented using
632%D \JAVASCRIPT, but nowadays more kind of actions are supported, so we can do
633%D without. The \MKIV\ version also supports definition of tooltips and
634%D configuration.
635%D
636%D \starttyping
637%D before \tooltip[right]{inbetween}{a very nice tip} after\par
638%D before \tooltip[align=normal]{inbetween}{a very\\nice tip} after\par
639%D before \tooltip[middle]{inbetween}{a very nice tip} after\par
640%D before \tooltip[left]{inbetween}{a very nice tip} after\par
641%D \stoptyping
642
643\newbox  \b_scrn_tooltip_anchor
644\newbox  \b_scrn_tooltip_text
645\newcount\c_scrn_tooltip_n
646
647\installcorenamespace{tooltip}
648
649\installframedcommandhandler \??tooltip {tooltip} \??tooltip
650
651\setuptooltip
652  [\c!location=\v!right,
653   \c!frame=\v!off,
654   \c!offset=.1ex,
655   \c!background=\v!color,
656   \c!backgroundcolor=gray]
657
658\appendtoks
659    \frozen\instance\setuevalue\currenttooltip{\scrn_tooltip_direct{\currenttooltip}}%
660\to \everydefinetooltip
661
662\protected\def\scrn_tooltip_direct#tag%
663  {\def\currenttooltip{#tag}%
664   \iflocation
665     \expandafter\scrn_tooltip_indeed
666   \else
667     \expandafter\scrn_tooltip_ignore
668   \fi}
669
670\tolerant\def\scrn_tooltip_ignore[#settings]#:#anchortext#tiptext%
671  {#anchortext}
672
673\mutable\let\currenttooltipname\empty
674
675\tolerant\def\scrn_tooltip_indeed[#settings]#:#anchortext#tiptext% a more modern aproach (push buttons)
676  {\dontleavehmode \hbox \bgroup
677     \dontcomplain
678     \global\advance\c_scrn_tooltip_n\plusone
679     \edef\currenttooltipname{tooltip:\number\c_scrn_tooltip_n}%
680     \setbox\b_scrn_tooltip_anchor\hbox
681       {\strut#anchortext}%
682     \doifelseassignment{#settings}
683       {\setupcurrenttooltip[#settings]}%
684       {\setupcurrenttooltip[\c!location=#settings]}%
685     \setbox\b_scrn_tooltip_text\hbox
686       {\lettooltipparameter\c!location\empty
687        \inheritedtooltipframed{#tiptext}}%
688     \definesymbol
689       [\currenttooltipname:txt]
690       [\copy\b_scrn_tooltip_text]%
691     \definefieldbody
692       [\currenttooltipname:txt]
693       [\c!type=push,
694        \c!width=\wd\b_scrn_tooltip_text,
695        \c!height=\ht\b_scrn_tooltip_text,
696        \c!depth=\dp\b_scrn_tooltip_text,
697        \c!option=\v!hidden,
698        \c!values=\currenttooltipname:txt]%
699     \setbox\b_scrn_tooltip_text\hbox
700       {\fieldbody[\currenttooltipname:txt]}%
701     \setbox\b_scrn_tooltip_text\hbox
702       {\strut\lower\dimexpr.25ex+\ht\b_scrn_tooltip_text\relax\box\b_scrn_tooltip_text}%
703     \edef\p_location{\tooltipparameter\c!location}%
704     \ifx\p_location\v!left
705       \hsmashed{\hskip\wd\b_scrn_tooltip_anchor\llap{\box\b_scrn_tooltip_text}}%
706     \orelse\ifx\p_location\v!middle
707       \hsmashed to \wd\b_scrn_tooltip_anchor{\hss\box\b_scrn_tooltip_text\hss}%
708     \else
709       \hsmashed{\box\b_scrn_tooltip_text}%
710     \fi
711     \definesymbol
712       [\currenttooltipname:but]
713       [\hphantom{\copy\b_scrn_tooltip_anchor}]%
714     \definefieldbody
715       [\currenttooltipname:but]
716       [\c!type=push,
717        \c!regionin=action(show{\currenttooltipname:txt}),
718        \c!regionout=action(hide{\currenttooltipname:txt}),
719        \c!width=\wd\b_scrn_tooltip_anchor,
720        \c!height=\ht\b_scrn_tooltip_anchor,
721        \c!depth=\dp\b_scrn_tooltip_anchor]%
722     \hsmashed{\fieldbody[\currenttooltipname:but]}%
723   \egroup
724   #anchortext}% when hyphenated the text wil stick out ... such are fields and we cannot use a link here
725
726\definetooltip[tooltip]
727
728%D From messages on the mailing list we can conclude that fieldstacks are used so we
729%D keep them in the core:
730%D
731%D \starttyping
732%D \definesymbol[one]  [one]
733%D \definesymbol[two]  [two]
734%D \definesymbol[three][three]
735%D
736%D \definefieldstack[mine][one,two,three]
737%D \fieldstack[mine]
738%D \fieldstack[mine]
739%D
740%D \goto{walk field}[Walk{mine}]
741%D \stoptyping
742
743% todo: expand #symbols
744
745\installcorenamespace {fieldstack}
746
747\permanent\tolerant\protected\def\definefieldstack[#tag]#spacer[#symbols]#spacer[#settings]%
748  {\ifcsname\??fieldstack#tag\endcsname
749     % already done
750   \else
751     %setgvalue{\??fieldstack#tag}{\scrn_fieldstack_construct[#tag][#symbols][#settings]}%
752     \setxvalue{\??fieldstack#tag}{\scrn_fieldstack_construct[#tag][#symbols][\normalunexpanded{#settings}]}%
753   \fi}
754
755\permanent\tolerant\protected\def\fieldstack[#tag]#spacer[#symbols]#spacer[#settings]%
756  {\ifparameter#symbols\or
757     \definefieldstack[#tag][#symbols][#settings]%
758   \fi
759   \csname\??fieldstack#tag\endcsname}
760
761\newbox\b_scrn_fieldstack_box
762
763\definesymbol[\s!empty][]
764
765\def\scrn_fieldstack_add#tag#settings#symbol%
766  {\advance\scratchcounter\plusone
767   \edef\currentfieldstackname{#tag:\number\scratchcounter}%
768   \ifnum\scratchcounter=\fieldcategoryparameter\c!start\relax
769     \definefieldbody[\currentfieldstackname][\c!type=check,\c!values={#symbol,\s!empty},\c!default={#symbol}]%
770   \else
771     \definefieldbody[\currentfieldstackname][\c!type=check,\c!values={#symbol,\s!empty},\c!default=\s!empty]%
772   \fi
773   \setbox\b_scrn_fieldstack_box\hbox{\symbol[#symbol]}%
774   \setcollector
775     [fieldstack]
776     {\fieldbody
777        [\currentfieldstackname]
778        [\c!option={\v!readonly},
779         \c!width=\wd\b_scrn_fieldstack_box,
780         \c!height=\ht\b_scrn_fieldstack_box,
781         \c!depth=\dp\b_scrn_fieldstack_box,
782         #settings]}}
783
784\protected\def\scrn_fieldstack_construct[#tag][#symbols][#settings]% start=n, 0 == leeg
785  {\iflocation
786     \dontleavehmode
787     \begingroup
788     \setupfieldcategory[\c!start=1,#settings]% was just \??fieldcategory
789     \scrn_field_load_scripts
790     \definecollector
791       [fieldstack]%
792       [\c!corner=\v!middle,
793        \c!location=\v!middle]%
794     \scratchcounter\zerocount
795     \processcommalist[#symbols]{\scrn_fieldstack_add{#tag}{#settings}}%
796     \flushcollector[fieldstack]%
797     \endgroup
798   \fi}
799
800%D Another goodie. Two actions can be hookes into an overlay.
801%D
802%D \starttyping
803%D \defineviewerlayer[test]
804%D
805%D \startviewerlayer[test]Hide Me\stopviewerlayer
806%D
807%D \defineoverlay
808%D   [WithTest]
809%D   [{\overlayrollbutton[HideLayer{test}][VideLayer{test}]}]
810%D
811%D \framed[background=WithTest]{toggle}
812%D \stoptyping
813
814\newcount\c_scrn_rollbutton_n
815
816\permanent\tolerant\protected\def\overlayrollbutton[#1]#*[#2]#;#=#=%
817  {\iflocation
818     \bgroup
819     \global\advance\c_scrn_rollbutton_n_button\plusone
820     \global\advance\c_scrn_rollbutton_n_symbol\plusone
821     \definesymbol
822       [rollsymbol:\number\c_scrn_rollbutton_n_symbol]
823       [{\framed[\c!frame=\v!off,\c!width=\overlaywidth,\c!height=\overlayheight]{}}]%
824   % \definefieldbody
825   %   [rollbutton:\number\c_scrn_rollbutton_n_button]
826   %   [\c!type=push,
827   %    \c!values=rollsymbol:\number\c_scrn_rollbutton_n_symbol,
828   %    \c!default=rollsymbol:\number\c_scrn_rollbutton_n_symbol]%
829   % \fitfield
830   %   [rollbutton:\number\c_scrn_rollbutton_n_button]%
831   %   [\c!regionin={#regionin},
832   %    \c!regionout={#regionout}]%
833     %
834     \definefield
835       [rollbutton:\number\c_scrn_rollbutton_n_button][push][rollbutton]
836       [rollsymbol:\number\c_scrn_rollbutton_n_symbol]%
837     \fitfield
838       [rollbutton:\number\c_scrn_rollbutton_n_button]%
839       [\c!regionin={#1#3},\c!regionout={#2#4}]%
840     %
841     \egroup
842   \fi}
843
844% \protect \endinput % THE FOLLOWING CODE IS NOT CHECKED
845
846%D I will redo these when I need them.
847
848% \setupinteraction[state=start]
849%
850% \definepushbutton [reset]
851%
852% \startuniqueMPgraphic{whatever}{color}
853%     fill fullcircle xysized (OverlayWidth,OverlayHeight) withcolor \MPvar{color} ;
854% \stopuniqueMPgraphic
855%
856% \definepushsymbol [reset] [n] [\uniqueMPgraphic{whatever}{color=red}]
857% \definepushsymbol [reset] [r] [\uniqueMPgraphic{whatever}{color=green}]
858% \definepushsymbol [reset] [d] [\uniqueMPgraphic{whatever}{color=blue}]
859%
860% \starttext
861%     \startTEXpage
862%         \pushbutton [reset] [page(2)]
863%     \stopTEXpage
864%     \startTEXpage
865%         \pushbutton [reset] [page(1)]
866%     \stopTEXpage
867% \stoptext
868
869\newcount\c_scrn_pushbutton_n
870
871\permanent\tolerant\protected\def\definepushbutton[#tag]#spacer[#settings]%
872  {\scrn_pushbutton_define_variant{#tag}{n}{push}%
873   \scrn_pushbutton_define_variant{#tag}{r}{\symbol[pushsymbol:#tag:n]}%
874   \scrn_pushbutton_define_variant{#tag}{d}{\symbol[pushsymbol:#tag:r]}%
875   \setvalue{pushbutton:#tag}{\scrn_pushbutton_handle{#tag}{#settings}}}
876
877\def\scrn_pushbutton_define_variant#tag#variant#content%
878  {\doifelsesymboldefined{pushsymbol:#tag:#variant}
879     \donothing
880     {\definesymbol[pushsymbol:#tag:#variant][{#content}]}}
881
882\def\scrn_pushbutton_handle#tag#settings#reference%
883  {\bgroup
884   \global\advance\c_scrn_pushbutton_n\plusone
885   \setupfield
886     [pushbutton]%
887     [\c!frame=\v!overlay,%
888      \c!offset=\v!overlay,%
889      \c!clickout={#reference},%
890      #settings]%
891   \definefield
892     [pushbutton:\number\c_scrn_pushbutton_n]%
893     [push]%
894     [pushbutton]%
895     [pushsymbol:#tag:n,pushsymbol:#tag:r,pushsymbol:#tag:d]%
896   \fitfield
897     [pushbutton:\number\c_scrn_pushbutton_n]%
898   \egroup}
899
900\permanent\tolerant\protected\def\definepushsymbol[#tag]#spacer[#variant]% [#reference]
901  {\definesymbol[pushsymbol:#tag:#variant]}
902
903\permanent\tolerant\def\pushbutton[#tag]#spacer[#variant]%
904  {\executeifdefined{pushbutton:#tag}\gobbleoneargument{#variant}}
905
906%D We plug into the menu system
907
908\permanent\permanent\protected\def\scrn_menu_psh_start[#reference]#text\stoppsh
909  {\starttxt\pushbutton[\currentinteractionmenu][#reference]\stoptxt}
910
911\permanent\permanent\protected\def\scrn_menu_psh_direct[#reference]#text\\
912  {\scrn_menu_psh_start[#reference]\stoprob}
913
914\aliased\let\startpsh\relax % maybe mutable
915\aliased\let\stoppsh \relax % maybe mutable
916\aliased\let\psh     \relax % maybe mutable
917
918\appendtoks
919    \enforced\let\startpsh\scrn_menu_psh_start
920    \enforced\let\stoppsh \relax
921    \enforced\let\psh     \scrn_menu_psh_direct
922\to \everysetmenucommands
923
924%D Another goodie: (unchecked in \MKIV)
925
926% calls:
927%              {..} [JS..]
928% [left]       {..} [JS..]
929%        [a=b] {..} [JS..]
930% [left] [a=b] {..} [JS..]
931%
932% \setupbuttons[offset=0pt,frame=off] % alternative=hidden
933%
934% \rollbutton {Manuals}       [JS(Goto_File{show-man.pdf})]
935% \rollbutton {Articles}      [JS(Goto_File{show-art.pdf})]
936% \rollbutton {Papers}        [JS(Goto_File{show-pap.pdf})]
937% \rollbutton {Presentations} [JS(Goto_File{show-pre.pdf})]
938% \rollbutton {Resources}     [JS(Goto_File{show-res.pdf})]
939%
940% \rob [JS(...)] bla bla \\
941
942% \definecolor[rollover:n][red]
943% \definecolor[rollover:r][green]
944% \definecolor[rollover:d][blue]
945
946\definepalet
947  [rollover]
948  [n=red,
949   r=green,
950   d=blue]
951
952\newcount\c_scrn_rollbutton_n_button
953\newcount\c_scrn_rollbutton_n_symbol
954
955\permanent\def\lastrollbuttonindex{\the\c_scrn_rollbutton_n_button}
956
957\setupfield
958  [rollbutton]
959  [\c!frame=\v!off,
960   \c!offset=\v!overlay]
961
962\let\scrn_rollbutton_symbol\relax
963
964\def\scrn_rollbutton_symbol_m
965  {\scrn_rollbutton_symbol_indeed
966     \interactionmenuparameter
967     \inheritedinteractionmenuframed
968     \setinteractionmenuparameter
969     \useinteractionmenustyleandcolor}
970
971\def\scrn_rollbutton_symbol_b
972  {\scrn_rollbutton_symbol_indeed
973     \buttonparameter
974     \inheritedbuttonframed
975     \setbuttonparameter
976     \usebuttonstyleandcolor}
977
978\permanent\tolerant\protected\def\rollbutton[#tag]#spacer[#settings]#:#text[#reference]%
979  {\dontleavehmode
980   \bgroup
981   \global\advance\c_scrn_rollbutton_n_button\plusone
982   \global\advance\c_scrn_rollbutton_n_symbol\plusone
983   \ifparameter#tag\or
984     \ifparameter#settings\or
985       \edef\currentinteractionmenu{#tag}%
986       \setupcurrentinteractionmenu[#settings]%
987       \let\scrn_rollbutton_symbol\scrn_rollbutton_symbol_m
988     \orelse\ifhastok={#tag}%
989       \let\currentbutton\empty
990       \setupcurrentbutton[#tag]%
991       \let\scrn_rollbutton_symbol\scrn_rollbutton_symbol_b
992     \else
993       \edef\currentinteractionmenu{#tag}%
994       \let\scrn_rollbutton_symbol\scrn_rollbutton_symbol_m
995     \fi
996   \else
997     \let\scrn_rollbutton_symbol\scrn_rollbutton_symbol_b
998   \fi
999   % todo: share symbols, tricky since different dimensions (maybe \unique...)
1000   \definesymbol[rollsymbol:\number\c_scrn_rollbutton_n_symbol:n][\scrn_rollbutton_symbol{n}{#text}]%
1001   \definesymbol[rollsymbol:\number\c_scrn_rollbutton_n_symbol:r][\scrn_rollbutton_symbol{r}{#text}]%
1002   \definesymbol[rollsymbol:\number\c_scrn_rollbutton_n_symbol:d][\scrn_rollbutton_symbol{d}{#text}]%
1003   \definefield
1004     [rollbutton:\number\c_scrn_rollbutton_n_button][push][rollbutton]
1005     [rollsymbol:\number\c_scrn_rollbutton_n_symbol:n,%
1006      rollsymbol:\number\c_scrn_rollbutton_n_symbol:r,%
1007      rollsymbol:\number\c_scrn_rollbutton_n_symbol:d]%
1008   \fitfield
1009     [rollbutton:\number\c_scrn_rollbutton_n_button]%
1010     [\c!clickout={#reference}]%
1011   \egroup}
1012
1013\protected\def\scrn_rollbutton_symbol_indeed#getparameter#inheritedframed#setparameter#usestyleandcolor#what#text%
1014  {\definecolor[rollover][rollover:#what]%
1015   \doifelse{#what}{n}% ?
1016     {\doifelse{#getparameter\c!alternative}\v!hidden\phantom\hbox}\hbox
1017        {#setparameter\c!framecolor     {rollover}%
1018         #setparameter\c!backgroundcolor{rollover}%
1019         #setparameter\c!color          {rollover}%
1020         #inheritedframed{#usestyleandcolor\c!style\c!color{#text}}}}
1021
1022%D We plug into the menu system
1023
1024\permanent\protected\def\scrn_menu_rob_start[#reference]#text\stoprob
1025  {\starttxt\rollbutton[\currentinteractionmenu]{\ignorespaces#text\unskip}[#reference]\stoptxt}
1026
1027\permanent\protected\def\scrn_menu_rob_direct[#reference]#text\\
1028  {\scrn_menu_rob_start[#reference]#text\stoprob}
1029
1030\aliased\let\startrob\relax % maybe mutable
1031\aliased\let\stoprob \relax % maybe mutable
1032\aliased\let\rob     \relax % maybe mutable
1033
1034\appendtoks
1035    \enforced\let\startrob\scrn_menu_rob_start
1036    \enforced\let\stoprob \relax
1037    \enforced\let\rob     \scrn_menu_rob_direct
1038\to \everysetmenucommands
1039
1040\protect \endinput
1041