%D \module %D [ file=scrn-fld, %D version=1997.05.18, %D title=\CONTEXT\ Screen Macros, %D subtitle=Fields, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. %D There is still some leftover code from mkii, where we need to be sparse with hash %D entries and so have a somewhat complex setup mechanism. It doesn't pay off to %D waste time on improving this because one never knows what happens with widgets %D in \PDF; it has a history of dropping features like this. Also, the implementation %D of fields fluctuates with versions. % interaction checking \writestatus{loading}{ConTeXt Screen Macros / Fields} \unprotect \registerctxluafile{scrn-fld}{} %D In \MKII\ we had to cheat a bit with setups in order not to run out of memory %D with thousands of fields, which we happen to need at that time. In \MKIV\ we can %D store some data at the \LUA\ end and use a somewhat slower but quite okay %D inheritance mechanism. For this reason we now have split definitions, although %D the old method is still somewhat supported. The clone and copy commands are %D somewhat obsolete for several reasons: we can now use inheritance and autocloning %D has been supported for a while. In most cases cloning (especially with check %D boxes) the acrobat browser is not stable enough with respect to appearance %D handling. %D %D A fieldcategory is nothing more than a collection of settings. %D %D \starttyping %D \definefieldcategory %D [all-email] %D [height=1cm, %D width=14cm, %D style=sstf] %D \stoptyping %D %D A definition can refer to this category: %D %D \starttyping %D \definefieldbody [email] [type=line,category=all-email,default=pragma@xs4all.nl] %D \stoptyping %D %D A copy of a field is made as follows: %D %D \starttyping %D \definefieldbody [xmail] [email] %D \stoptyping %D %D You can also be more specific: %D %D \starttyping %D \definefieldbody[buttona][type=check,values={one,two}] %D \definefieldbody[buttonb][type=check,values={three,four}] %D \definefieldbody[buttonc][buttona][values={three,four}] %D \stoptyping %D %D Actually typesetting a field happens this way: %D %D \starttyping %D \fieldbody [Email] %D \fieldbody [Email] [width=6cm] %D \fieldbody [eMAIL] %D \fieldbody [eMAIL] [width=7cm] %D %D \fieldbody [buttona] %D \fieldbody [buttona] %D \fieldbody [buttonb] %D \fieldbody [buttonb] %D \fieldbody [buttonc] %D \fieldbody [buttonc] %D \stoptyping %D %D So, you can call up a field many times and quite some parameters can be set. %D %D Because there are persistent problems with acrobat rendering associated %D appearance streams (some messy /MK interferende) we also support native (built-in %D dingbat) symbols: check, circle, cross, diamond, square and star. %D %D \starttyping %D \definefield[test1][check] %D \definefield[test2][check] %D %D \fieldbody[test1][width=1em,height=\strutht,depth=\strutdp,symbol=check] %D \fieldbody[test1][width=1em,height=\strutht,depth=\strutdp,symbol=circle] %D \fieldbody[test2][width=1em,height=\strutht,depth=\strutdp,symbol=square] %D \stoptyping %D %D When submitting a form, we need to tell the driver module that we want \FDF\ or %D \HTML. \installcorenamespace {forms} \installdirectcommandhandler \??forms {forms} \appendtoks \clf_setformsmethod{\formsparameter\c!method}% \to \everysetupforms \setupforms [\c!method=XML] % no need for everyjob initialization as this is the default \mutable\lettonothing\currentfieldbackgroundcolor \mutable\lettonothing\currentfieldbackgroundcolorvalue \mutable\lettonothing\currentfieldbodycategory \mutable\lettonothing\currentfieldframecolor \mutable\lettonothing\currentfieldframecolorvalue \mutable\lettonothing\currentfieldlabel \mutable\lettonothing\currentfieldstackname \appendtoks \iflocation \clf_exportformdata{\formsparameter\c!export}% \fi \to \everystoptext %D We need to initialize symbols in a special way so that they can be used as %D rendering for a widget. \permanent\protected\def\presetfieldsymbols[#list]% slow {\processcommacommand[#list]\scrn_symbols_preset} \def\scrn_symbols_preset#set% {\processcommalist[#set]\scrn_symbols_preset_indeed}% \permanent\protected\def\scrn_symbols_preset_indeed#tag% {\doifelseobjectfound{SYM}{#tag} {} {\settightobject{SYM}{#tag}\hbox{\symbol[#tag]}% % todo: set this as immediate xform \page_otr_add_special_content{\hskip-\maxdimen\getobject{SYM}{#tag}}}} % and then force it into the file \aliased\let\dosetfieldsymbol\scrn_symbols_preset_indeed \permanent\def\dogetfieldsymbol#tag% {\getobject{SYM}{#tag}} \permanent\protected\def\definedefaultsymbols % used ? {\definesymbol[defaultyes][\mathematics{\times}]% \definesymbol[defaultno] [\mathematics{\cdot }]} %D Now comes the real code: \installcorenamespace{fieldcategory} \installcorenamespace{fieldbody} \installcommandhandler \??fieldcategory {fieldcategory} \??fieldcategory \installcommandhandler \??fieldbody {fieldbody} \??fieldbody \newbox\b_scrn_field_body \setupfieldcategory [\c!alternative=\v!normal, % normal clone copy \c!type=\v!line, % line text ... \c!width=5em, \c!height=1em, \c!depth=\zeropoint, \c!align=\v!flushleft, \c!option=\v!printable, % maybe we need a globaloptions and marge them \c!n=1024] \def\scrn_field_check_category {\edef\currentfieldbodycategory{\fieldbodyparameter\c!category}% \ifempty\currentfieldbodycategory \letfieldbodyparameter\s!parent\??fieldcategory %\setevalue{\currentfieldbodyhash\s!parent}{\namedfieldcategoryhash\empty}% to WS: not hash ! \else \normalexpanded{\setfieldbodyparameter{\s!parent}{\??fieldcategory\currentfieldbodycategory}}% %\setevalue{\currentfieldbodyhash\s!parent}{\namedfieldcategoryhash\currentfieldbodycategory}% to WS: not hash ! \fi} \appendtoks % we cannot use parent .. maybe s!parent has to change \ifempty\currentfieldbodyparent \scrn_field_check_category \clf_definefield name {\currentfieldbody}% alternative {normal}% type {\fieldbodyparameter\c!type}% category {\fieldbodyparameter\c!category}% values {\fieldbodyparameter\c!values}% default {\fieldbodyparameter\c!default}% \relax \else \clf_clonefield children {\currentfieldbody}% alternative {clone}% parent {\currentfieldbodyparent}% category {\fieldbodyparameter\c!category}% values {\fieldbodyparameter\c!values}% default {\fieldbodyparameter\c!default}% \relax \fi \to \everydefinefieldbody \permanent\tolerant\protected\def\fieldbody[#tag]#spacer[#S#settings]% {\iflocation \hbox\bgroup \edef\currentfieldbody{#tag}% \setupcurrentfieldbody[#settings]% \scrn_field_body_typeset \box\b_scrn_field_body \egroup \fi} \def\scrn_field_body_typeset % todo: fieldsymbol (checkfields /MK mess) {\edef\currentfieldframecolor{\fieldbodyparameter\c!fieldframecolor}% \ifempty\currentfieldframecolor\else \getcolorattributevalue\currentfieldframecolor\currentfieldframecolorvalue % == \edef\currentfieldframecolorvalue{\thecolorattribute\currentfieldframecolor}% \fi \edef\currentfieldbackgroundcolor{\fieldbodyparameter\c!fieldbackgroundcolor}% \ifempty\currentfieldbackgroundcolor\else \getcolorattributevalue\currentfieldbackgroundcolor\currentfieldbackgroundcolorvalue % == \edef\currentfieldbackgroundcolorvalue{\thecolorattribute\currentfieldbackgroundcolor}% \fi \usefieldbodystyleandcolor\c!style\c!color \clf_insertfield {\currentfieldbody}% {% title {\currentfieldbody} width \dimexpr\fieldbodyparameter\c!width \relax height \dimexpr\fieldbodyparameter\c!height\relax depth \dimexpr\fieldbodyparameter\c!depth \relax align {\fieldbodyparameter\c!align}% length {\fieldbodyparameter\c!n}% fontstyle {\fontstyle}% fontalternative {\fontalternative}% fontsize {\fontbody}% fontsymbol {\fieldbodyparameter\c!symbol}% color {\fieldbodyparameter\c!color}% colorvalue \c_attr_color \ifempty\currentfieldbackgroundcolor \else backgroundcolor {\currentfieldbackgroundcolor}% backgroundcolorvalue \numexpr\currentfieldbackgroundcolorvalue\relax \fi \ifempty\currentfieldframecolor \else framecolor {\currentfieldframecolor}% framecolorvalue \numexpr\currentfieldframecolorvalue\relax \fi layer {\fieldbodyparameter\c!fieldlayer}% option {\fieldbodyparameter\c!option}% clickin {\fieldbodyparameter\c!clickin}% clickout {\fieldbodyparameter\c!clickout}% regionin {\fieldbodyparameter\c!regionin}% regionout {\fieldbodyparameter\c!regionout}% afterkey {\fieldbodyparameter\c!afterkey}% format {\fieldbodyparameter\c!format}% validate {\fieldbodyparameter\c!validate}% calculate {\fieldbodyparameter\c!calculate}% focusin {\fieldbodyparameter\c!focusin}% focusout {\fieldbodyparameter\c!focusout}% openpage {\fieldbodyparameter\c!openpage}% closepage {\fieldbodyparameter\c!closepage}% }% \relax} %D The sets are used in grouped calculations. %D %D [name] [set] \permanent\tolerant\protected\def\definefieldbodyset[#tag]#spacer[#list]% {\clf_definefieldset{#tag}{#list}} \aliased\let\dodefinefieldset\definefieldbodyset % compatibility %D A few testing macros (expandable for historic reasons): \permanent\def\doifelsefieldbody #tag{\clf_doifelsefieldset{#tag}} \permanent\def\doifelsefieldcategory#tag{\clf_doifelsefieldcategory{#tag}} \aliased\let\doiffieldbodyelse \doifelsefieldbody \aliased\let\doiffieldcategoryelse\doifelsefieldcategory \aliased\let\doiffieldelse \doifelsefieldbody % compatibility / will be dropped \aliased\let\doifelsefield \doifelsefieldbody % compatibility / will be dropped %D We still support the traditional method of defining fields: %D %D \starttyping %D \definefield [name] [type] [category] [values] [default] %D %D \definefield [WWWW] [text] [textsetup] [default text] %D \definefield [XXXX] [push] [pushsetup] [yes,no] [yes] %D \definefield [XXXX] [check] [checksetup] [yes,no] [yes] %D \definefield [YYYY] [combo] [combosetup] [a,b,c,d] [b] %D \definefield [ZZZZ] [radio] [radiosetup] [W,X,Y,Z] [Y] %D %D \definesubfield [W] [subsetup] [p,q] %D \definesubfield [X,Y] [subsetup] [p,r] %D \definesubfield [Z] [subsetup] [y,z] %D %D evt \definemainfield ... wanneer geplaatst voor subs gegeven %D %D \clonefield [XXXX] [XX,YY] [mysetup] [on,off] %D \clonefield [Z] [AA,BB] [somesetup] [true,false] %D \clonefield [Z] [CC,DD] [anothersetup] %D %D \copyfield [XXXX] [PP,QQ,RR] %D \stoptyping %D %D Keep in mind that you can also use \type {\definefieldbody} to achieve the same. \permanent\tolerant\protected\def\definefield[#tag]#spacer[#type]#spacer[#category]#spacer[#values]#spacer[#default]% {\definefieldbody[#tag][\c!type=#type,\c!category=#category,\c!values={#values},\c!default={#default}]} \permanent\tolerant\protected\def\definesubfield[#tag]#spacer[#category]#spacer[#values]% {\definefieldbody[#tag][\c!type=sub,\c!category=#category,\c!values={#values}]} \permanent\tolerant\protected\def\clonefield[#parent]#spacer[#tag]#spacer[#category]#spacer[#values]% {\definefieldbody[#tag][#parent][\c!category=#category,\c!values={#values}]} \permanent\tolerant\protected\def\copyfield[#parent]#spacer[#tag]% {\definefieldbody[#tag][#parent]} \aliased\let\definemainfield\definefield % obsolete ! %D We hook fields into the (viewer based) layering mechanism %D (implemented as properties). \appendtoks \lettonothing\currentfieldcategory \ifcstok{\interactionparameter\c!fieldlayer}\v!auto \setupcurrentfieldcategory[\c!fieldlayer=\currentviewerlayer]% \else \setupcurrentfieldcategory[\c!fieldlayer=]% \fi \to \everysetupinteraction \setupinteraction [\c!fieldlayer=\v!auto] % auto by default %D The \type {\fieldbody} is the more bare one. One step further goes \type %D {\fitfield}, in fact it (now) uses a dedicated instance of framed: \type %D {fitfieldframed}. %D %D \starttyping %D \ruledhbox{\fieldbody[Email][height=\strutht,depth=\strutdp,style=normal]} %D \ruledhbox{\fitfield[Email][height=\strutht,depth=\strutdp,style=normal]} %D \ruledhbox{\fitfield[buttona]} %D \stoptyping \newbox\b_scrn_field_fit_symbol \defineframed [fitfieldframed] [\c!strut=\v!no, \c!frame=off, \c!offset=\v!overlay, \c!align=] \permanent\tolerant\protected\def\fitfield[#tag]#spacer[#S#settings]% {\iflocation \begingroup \setbox\b_scrn_field_fit_symbol\hbox\bgroup \normalexpanded{\symbol[\clf_getdefaultfieldvalue{#tag}]}% \egroup \fitfieldframed {\fieldbody[#tag] [\c!width=\wd\b_scrn_field_fit_symbol, \c!height=\ht\b_scrn_field_fit_symbol, \c!depth=\dp\b_scrn_field_fit_symbol, #settings]}% \endgroup \fi} %D The traditional field command does some labeling and boxing: \installcorenamespace{fieldlabel} \installcorenamespace{fieldcontent} \installcorenamespace{fieldtotal} \installparameterhandler \??fieldlabel {fieldlabelframed} \installparameterhandler \??fieldcontent {fieldcontentframed} \installparameterhandler \??fieldtotal {fieldtotalframed} \installparametersethandler \??fieldcontent {fieldcontentframed} \installsetuphandler \??fieldlabel {fieldlabelframed} \installsetuphandler \??fieldcontent {fieldcontentframed} \installsetuphandler \??fieldtotal {fieldtotalframed} \installinheritedframed {fieldlabelframed} \installinheritedframed {fieldcontentframed} \installinheritedframed {fieldtotalframed} \setupfieldcontentframed [\c!align=\v!flushleft, \c!strut=\v!no, \s!parent=\??regularframed] % needs checking \setupfieldcontentframed % independent [\c!alternative=\v!normal, \c!type=\v!line, \c!width=5em, \c!height=\lineheight, \c!depth=\zeropoint, \c!align=\v!flushleft, \c!option=\v!printable, \c!n=1024] \setupfieldlabelframed [\c!style=, \c!color=, \c!align=\v!flushleft, \s!parent=\??regularframed] % needs checking \setupfieldtotalframed [%\c!alternative={\v!label,\v!frame,\v!horizontal}, \c!strut=\v!no, \c!align=, \s!parent=\??regularframed] % needs checking % \setupcurrent \permanent\tolerant\protected\def\setupfield[#tag]#spacer[#variant]#spacer[#S#totalsettings]#spacer[#S#labelsettings]#spacer[#S#fieldsettings]% {\ifarguments\or\or \definefieldcategory[#tag][\s!parent=\??fieldcontent#tag,#variant]% \setupfieldtotalframed [#tag][\s!parent=\??fieldtotal]% \setupfieldlabelframed [#tag][\s!parent=\??fieldlabel]% \setupfieldcontentframed[#tag][\s!parent=\??fieldcontent,#variant]% \or \definefieldcategory[#tag][\s!parent=\??fieldcontent#tag,#totalsettings]% \setupfieldtotalframed [#tag][\s!parent=\??fieldtotal,\c!alternative={#variant}]% \setupfieldlabelframed [#tag][\s!parent=\??fieldlabel]% \setupfieldcontentframed[#tag][\s!parent=\??fieldcontent,#totalsettings]% \or \definefieldcategory[#tag][\s!parent=\??fieldcontent#tag,#labelsettings]% \setupfieldtotalframed [#tag][\s!parent=\??fieldtotal,\c!alternative={#variant},#totalsettings]% \setupfieldlabelframed [#tag][\s!parent=\??fieldlabel]% \setupfieldcontentframed[#tag][\s!parent=\??fieldcontent,#labelsettings]% \or \definefieldcategory[#tag][\s!parent=\??fieldcontent#tag,#fieldsettings]% \setupfieldtotalframed [#tag][\s!parent=\??fieldtotal,\c!alternative={#variant},#totalsettings]% \setupfieldlabelframed [#tag][\s!parent=\??fieldlabel,#labelsettings]% \setupfieldcontentframed[#tag][\s!parent=\??fieldcontent,#fieldsettings]% \fi} \permanent\tolerant\protected\def\setupfields[#variant]#spacer[#S#totalsettings]#spacer[#S#labelsettings]#spacer[#S#fieldsettings]% {\ifarguments\or \setupfieldtotalframed [#variant]% \or \setupfieldtotalframed [#variant]% \setupfieldcontentframed[#totalsettings]% \or \setupfieldtotalframed [#variant]% \setupfieldlabelframed [#totalsettings]% \setupfieldcontentframed[#labelsettings]% \or \setupfieldtotalframed [\c!alternative={#variant},#totalsettings]% \setupfieldlabelframed [#labelsettings]% \setupfieldcontentframed[#fieldsettings]% \fi} % just to get the chain right for no category: \definefieldcategory [][\s!parent=\??fieldcontent] %setupfieldtotalframed [][\s!parent=\??fieldtotal] %setupfieldlabelframed [][\s!parent=\??fieldlabel] %setupfieldcontentframed[][\s!parent=\??fieldcontent] % no longer supported: % \let\resetfields\relax \def\scrn_field_load_scripts{\useJSscripts[fld]\glet\scrn_field_load_scripts\relax} \newconditional\fieldlabelshown \newconditional\fieldframeshown \newconditional\fieldisvertical \newconditional\fieldishorizontal \mutable\lettonothing\currentfieldtotalframed \mutable\lettonothing\currentfieldlabelframed \mutable\lettonothing\currentfieldcontentframed \mutable\lettonothing\fieldtotalframedparameterhash % weird that we have to flag this \mutable\lettonothing\fieldlabelframedparameterhash % idem \mutable\lettonothing\fieldcontentframedparameterhash % idem \permanent\tolerant\protected\def\field[#tag]#spacer[#label]% can be sped up with \setupcurrentfieldtotalframed etc {\iflocation \dontleavehmode \begingroup \scrn_field_load_scripts \edef\currentfieldbody {#tag}% \edef\currentfieldlabel {#label}% \edef\currentfieldcategory{\clf_getfieldcategory{#tag}}% \ifempty\currentfieldlabel \let\currentfieldlabel\currentfieldbody \fi \ifempty\currentfieldcategory \setupfieldtotalframed [\currentfieldbody][\s!parent=\??fieldtotal]% \setupfieldlabelframed [\currentfieldbody][\s!parent=\??fieldlabel]% \setupfieldcontentframed[\currentfieldbody][\s!parent=\??fieldcontent]% \definefieldcategory [\currentfieldbody]% \setupfieldbody [\currentfieldbody][\c!category=\currentfieldbody]% \let\currentfieldcategory\currentfieldbody \fi \let\currentfieldtotalframed \currentfieldcategory \let\currentfieldlabelframed \currentfieldcategory \let\currentfieldcontentframed\currentfieldcategory \scrn_field_analyze_setups \ifconditional\fieldframeshown \inheritedfieldtotalframedframed % lower framedoffset \bgroup \else \vbox \bgroup \fi \dontcomplain \ifconditional\fieldlabelshown \scrn_field_set_label_box \fi \scrn_field_set_content_box \ifconditional\fieldlabelshown \ifconditional\fieldisvertical \scrn_field_flush_vertical \else \scrn_field_flush_horizontal \fi \else \scrn_field_flush_content \fi \egroup \endgroup \fi} % opties: veld, label, kader, vertikaal/horizontaal \newbox\b_scrn_field_label \newbox\b_scrn_field_content % lower framedoffset \def\scrn_field_set_label_box {\setbox\b_scrn_field_label\hbox {\reshapeframeboxtrue % else wrong dimensions % still needed? \inheritedfieldlabelframedframed{\currentfieldlabel}}} % \c!fieldoffset=-\framedoffset,\c!fieldbackgroundcolor=, % \hbox{\lower\@@fdfieldoffset\hbox{\typesetfield}} \def\scrn_field_set_content_box {\setbox\b_scrn_field_content\hbox {\reshapeframeboxtrue % else wrong dimensions (to be checked) \ifempty{\fieldcontentframedparameter\c!height}% \ifconditional\fieldisvertical \setfieldcontentframedparameter\c!height{6ex}% \orelse\ifconditional\fieldishorizontal \setfieldcontentframedparameter\c!height{\vsize}% \else \setfieldcontentframedparameter\c!height{2cm}% \fi \fi \ifempty{\fieldcontentframedparameter\c!width}% \ifconditional\fieldisvertical \setfieldcontentframedparameter\c!width{\hsize}% \orelse\ifconditional\fieldishorizontal \setfieldcontentframedparameter\c!width{20em}% \else \setfieldcontentframedparameter\c!width{2cm}% \fi \fi \inheritedfieldcontentframedframed % lower framedoffset {\fieldbody [\currentfieldbody] [\c!width=\framedwidth,\c!height=\framedheight]}}} \def\scrn_field_flush_vertical {\vbox {\copy\b_scrn_field_label \fieldtotalframedparameter\c!inbetween \copy\b_scrn_field_content}} \def\scrn_field_flush_horizontal {\hbox {\vbox \ifdim\ht\b_scrn_field_content>\ht\b_scrn_field_label to \ht\b_scrn_field_content \fi {\fieldtotalframedparameter\c!before \copy\b_scrn_field_label \fieldtotalframedparameter\c!after}% \hskip\fieldtotalframedparameter\c!distance \vbox \ifdim\ht\b_scrn_field_label>\ht\b_scrn_field_content to \ht\b_scrn_field_label \fi {\fieldtotalframedparameter\c!before \box\b_scrn_field_content \fieldtotalframedparameter\c!after}}} \def\scrn_field_flush_content {\box\b_scrn_field_content} %D todo: replace \processallactionsinset \def\scrn_field_analyze_setups {\fieldlabelshown\conditionalfalse \fieldframeshown\conditionalfalse \fieldishorizontal\conditionalfalse \fieldisvertical\conditionalfalse \normalexpanded{\processallactionsinset[\fieldtotalframedparameter\c!alternative]} [ \v!reset=>\fieldlabelshown\conditionalfalse \fieldframeshown\conditionalfalse \fieldishorizontal\conditionalfalse \fieldisvertical\conditionalfalse, \v!label=>\fieldlabelshown\conditionaltrue, \v!frame=>\fieldframeshown\conditionaltrue, \v!horizontal=>\fieldishorizontal\conditionaltrue, \v!vertical=>\fieldisvertical\conditionaltrue]% \ifconditional\fieldisvertical \setupfieldtotalframed[\c!distance=\zeropoint,\c!inbetween=\vskip\d_framed_local_offset,\c!align=\v!right,\c!width=20em]% \orelse\ifconditional\fieldishorizontal \setupfieldtotalframed[\c!distance=\d_framed_local_offset,\c!inbetween=,\c!align=\c!left,\c!height=10ex]% \else \setupfieldtotalframed[\c!distance=\zeropoint,\c!inbetween=,\c!align=\c!left]% \fi \setupfieldtotalframed[\c!n=,\c!before=,\c!after=\vss,\c!style=,\c!color=]} %D Common stuff (obsolete) \newinteger\c_scrn_field_system_n \permanent\def\currentsystemfield{sys::\the\c_scrn_field_system_n} \permanent\protected\def\nextsystemfield {\global\advanceby\c_scrn_field_system_n\plusone} %D \CONTEXT\ had tooltips right from the moment that it supported fields. Due to the %D at that moment somewhat limited \PDF\ specification, they were implemented using %D \JAVASCRIPT, but nowadays more kind of actions are supported, so we can do %D without. The \MKIV\ version also supports definition of tooltips and %D configuration. %D %D \starttyping %D before \tooltip[right]{inbetween}{a very nice tip} after\par %D before \tooltip[align=normal]{inbetween}{a very\\nice tip} after\par %D before \tooltip[middle]{inbetween}{a very nice tip} after\par %D before \tooltip[left]{inbetween}{a very nice tip} after\par %D \stoptyping \newbox \b_scrn_tooltip_anchor \newbox \b_scrn_tooltip_text \newinteger\c_scrn_tooltip_n \installcorenamespace{tooltip} \installframedcommandhandler \??tooltip {tooltip} \??tooltip \setuptooltip [\c!location=\v!right, \c!frame=\v!off, \c!offset=.1ex, \c!background=\v!color, \c!backgroundcolor=gray] \appendtoks \frozen\instance\protected\edefcsname\currenttooltip\endcsname{\scrn_tooltip_direct{\currenttooltip}}% \to \everydefinetooltip \protected\def\scrn_tooltip_direct#tag% {\cdef\currenttooltip{#tag}% \iflocation \expandafter\scrn_tooltip_indeed \else \expandafter\scrn_tooltip_ignore \fi} \tolerant\def\scrn_tooltip_ignore[#S#settings]#:#anchortext#tiptext% {#anchortext} \mutable\lettonothing\currenttooltipname \tolerant\def\scrn_tooltip_indeed[#S#settings]#:#anchortext#tiptext% a more modern aproach (push buttons) {\dontleavehmode \hbox \bgroup \dontcomplain \global\advanceby\c_scrn_tooltip_n\plusone \edef\currenttooltipname{tooltip:\the\c_scrn_tooltip_n}% \setbox\b_scrn_tooltip_anchor\hbox {\strut#anchortext}% \doifelseassignment{#settings} {\setupcurrenttooltip[#settings]}% {\setupcurrenttooltip[\c!location=#settings]}% \setbox\b_scrn_tooltip_text\hbox {\resettooltipparameter\c!location \inheritedtooltipframed{#tiptext}}% \definesymbol [\currenttooltipname:txt] [\copy\b_scrn_tooltip_text]% \definefieldbody [\currenttooltipname:txt] [\c!type=push, \c!width=\wd\b_scrn_tooltip_text, \c!height=\ht\b_scrn_tooltip_text, \c!depth=\dp\b_scrn_tooltip_text, \c!option=\v!hidden, \c!values=\currenttooltipname:txt]% \setbox\b_scrn_tooltip_text\hbox {\fieldbody[\currenttooltipname:txt]}% \setbox\b_scrn_tooltip_text\hbox {\strut\lower\dimexpr.25ex+\ht\b_scrn_tooltip_text\relax\box\b_scrn_tooltip_text}% \edef\p_location{\tooltipparameter\c!location}% \ifx\p_location\v!left \hsmashed{\hskip\wd\b_scrn_tooltip_anchor\llap{\box\b_scrn_tooltip_text}}% \orelse\ifx\p_location\v!middle \hsmashed to \wd\b_scrn_tooltip_anchor{\hss\box\b_scrn_tooltip_text\hss}% \else \hsmashed{\box\b_scrn_tooltip_text}% \fi \definesymbol [\currenttooltipname:but] [\hphantom{\copy\b_scrn_tooltip_anchor}]% \definefieldbody [\currenttooltipname:but] [\c!type=push, \c!regionin=action(show{\currenttooltipname:txt}), \c!regionout=action(hide{\currenttooltipname:txt}), \c!width=\wd\b_scrn_tooltip_anchor, \c!height=\ht\b_scrn_tooltip_anchor, \c!depth=\dp\b_scrn_tooltip_anchor]% \hsmashed{\fieldbody[\currenttooltipname:but]}% \egroup #anchortext}% when hyphenated the text wil stick out ... such are fields and we cannot use a link here \definetooltip[tooltip] %D From messages on the mailing list we can conclude that fieldstacks are used so we %D keep them in the core: %D %D \starttyping %D \definesymbol[one] [one] %D \definesymbol[two] [two] %D \definesymbol[three][three] %D %D \definefieldstack[mine][one,two,three] %D \fieldstack[mine] %D \fieldstack[mine] %D %D \goto{walk field}[Walk{mine}] %D \stoptyping % todo: expand #symbols \installcorenamespace {fieldstack} \permanent\tolerant\protected\def\definefieldstack[#tag]#spacer[#symbols]#spacer[#S#settings]% {\ifcsname\??fieldstack#tag\endcsname % already done \else %xdefcsname\??fieldstack#tag\endcsname{\scrn_fieldstack_construct[#tag][#symbols][#settings]}% \xdefcsname\??fieldstack#tag\endcsname{\scrn_fieldstack_construct[#tag][#symbols][\normalunexpanded{#settings}]}% \fi} \permanent\tolerant\protected\def\fieldstack[#tag]#spacer[#symbols]#spacer[#S#settings]% {\ifparameter#symbols\or \definefieldstack[#tag][#symbols][#settings]% \fi \csname\??fieldstack#tag\endcsname} \newbox\b_scrn_fieldstack_box \definesymbol[\s!empty][] \def\scrn_fieldstack_add#tag#settings#symbol% {\advanceby\scratchcounter\plusone \edef\currentfieldstackname{#tag:\the\scratchcounter}% \ifnum\scratchcounter=\fieldcategoryparameter\c!start\relax \definefieldbody[\currentfieldstackname][\c!type=check,\c!values={#symbol,\s!empty},\c!default={#symbol}]% \else \definefieldbody[\currentfieldstackname][\c!type=check,\c!values={#symbol,\s!empty},\c!default=\s!empty]% \fi \setbox\b_scrn_fieldstack_box\hbox{\symbol[#symbol]}% \setcollector [fieldstack] {\fieldbody [\currentfieldstackname] [\c!option={\v!readonly}, \c!width=\wd\b_scrn_fieldstack_box, \c!height=\ht\b_scrn_fieldstack_box, \c!depth=\dp\b_scrn_fieldstack_box, #settings]}} \protected\def\scrn_fieldstack_construct[#tag][#symbols][#S#settings]% start=n, 0 == leeg {\iflocation \dontleavehmode \begingroup \setupfieldcategory[\c!start=1,#settings]% was just \??fieldcategory \scrn_field_load_scripts \definecollector [fieldstack]% [\c!corner=\v!middle, \c!location=\v!middle]% \scratchcounter\zerocount \processcommalist[#symbols]{\scrn_fieldstack_add{#tag}{#settings}}% \flushcollector[fieldstack]% \endgroup \fi} %D Another goodie. Two actions can be hookes into an overlay. %D %D \starttyping %D \defineviewerlayer[test] %D %D \startviewerlayer[test]Hide Me\stopviewerlayer %D %D \defineoverlay %D [WithTest] %D [{\overlayrollbutton[HideLayer{test}][VideLayer{test}]}] %D %D \framed[background=WithTest]{toggle} %D \stoptyping \newinteger\c_scrn_rollbutton_n \permanent\tolerant\protected\def\overlayrollbutton[#1]#*[#2]#;#=#=% {\iflocation \bgroup \global\advanceby\c_scrn_rollbutton_n_button\plusone \global\advanceby\c_scrn_rollbutton_n_symbol\plusone \definesymbol [rollsymbol:\the\c_scrn_rollbutton_n_symbol] [{\framed[\c!frame=\v!off,\c!width=\overlaywidth,\c!height=\overlayheight]{}}]% % \definefieldbody % [rollbutton:\the\c_scrn_rollbutton_n_button] % [\c!type=push, % \c!values=rollsymbol:\the\c_scrn_rollbutton_n_symbol, % \c!default=rollsymbol:\the\c_scrn_rollbutton_n_symbol]% % \fitfield % [rollbutton:\the\c_scrn_rollbutton_n_button]% % [\c!regionin={#regionin}, % \c!regionout={#regionout}]% % \definefield [rollbutton:\the\c_scrn_rollbutton_n_button][push][rollbutton] [rollsymbol:\the\c_scrn_rollbutton_n_symbol]% \fitfield [rollbutton:\the\c_scrn_rollbutton_n_button]% [\c!regionin={#1#3},\c!regionout={#2#4}]% % \egroup \fi} % \protect \endinput % THE FOLLOWING CODE IS NOT CHECKED %D I will redo these when I need them. % \setupinteraction[state=start] % % \definepushbutton [reset] % % \startuniqueMPgraphic{whatever}{color} % fill fullcircle xysized (OverlayWidth,OverlayHeight) withcolor \MPvar{color} ; % \stopuniqueMPgraphic % % \definepushsymbol [reset] [n] [\uniqueMPgraphic{whatever}{color=red}] % \definepushsymbol [reset] [r] [\uniqueMPgraphic{whatever}{color=green}] % \definepushsymbol [reset] [d] [\uniqueMPgraphic{whatever}{color=blue}] % % \starttext % \startTEXpage % \pushbutton [reset] [page(2)] % \stopTEXpage % \startTEXpage % \pushbutton [reset] [page(1)] % \stopTEXpage % \stoptext \newinteger\c_scrn_pushbutton_n \permanent\tolerant\protected\def\definepushbutton[#tag]#spacer[#S#settings]% {\scrn_pushbutton_define_variant{#tag}{n}{push}% \scrn_pushbutton_define_variant{#tag}{r}{\symbol[pushsymbol:#tag:n]}% \scrn_pushbutton_define_variant{#tag}{d}{\symbol[pushsymbol:#tag:r]}% \setvalue{pushbutton:#tag}{\scrn_pushbutton_handle{#tag}{#settings}}} \def\scrn_pushbutton_define_variant#tag#variant#content% {\doifelsesymboldefined{pushsymbol:#tag:#variant} \donothing {\definesymbol[pushsymbol:#tag:#variant][{#content}]}} \def\scrn_pushbutton_handle#tag#settings#reference% {\bgroup \global\advanceby\c_scrn_pushbutton_n\plusone \setupfield [pushbutton]% [\c!frame=\v!overlay,% \c!offset=\v!overlay,% \c!clickout={#reference},% #settings]% \definefield [pushbutton:\the\c_scrn_pushbutton_n]% [push]% [pushbutton]% [pushsymbol:#tag:n,pushsymbol:#tag:r,pushsymbol:#tag:d]% \fitfield [pushbutton:\the\c_scrn_pushbutton_n]% \egroup} \permanent\tolerant\protected\def\definepushsymbol[#tag]#spacer[#variant]% [#reference] {\definesymbol[pushsymbol:#tag:#variant]} \permanent\tolerant\def\pushbutton[#tag]#spacer[#variant]% {\executeifdefined{pushbutton:#tag}\gobbleoneargument{#variant}} %D We plug into the menu system \permanent\permanent\protected\def\scrn_menu_psh_start[#reference]#text\stoppsh {\starttxt\pushbutton[\currentinteractionmenu][#reference]\stoptxt} \permanent\permanent\protected\def\scrn_menu_psh_direct[#reference]#text\\ {\scrn_menu_psh_start[#reference]\stoprob} \aliased\let\startpsh\relax % maybe mutable \aliased\let\stoppsh \relax % maybe mutable \aliased\let\psh \relax % maybe mutable \appendtoks \enforced\let\startpsh\scrn_menu_psh_start \enforced\let\stoppsh \relax \enforced\let\psh \scrn_menu_psh_direct \to \everysetmenucommands %D Another goodie: (unchecked in \MKIV) % calls: % {..} [JS..] % [left] {..} [JS..] % [a=b] {..} [JS..] % [left] [a=b] {..} [JS..] % % \setupbuttons[offset=0pt,frame=off] % alternative=hidden % % \rollbutton {Manuals} [JS(Goto_File{show-man.pdf})] % \rollbutton {Articles} [JS(Goto_File{show-art.pdf})] % \rollbutton {Papers} [JS(Goto_File{show-pap.pdf})] % \rollbutton {Presentations} [JS(Goto_File{show-pre.pdf})] % \rollbutton {Resources} [JS(Goto_File{show-res.pdf})] % % \rob [JS(...)] bla bla \\ % \definecolor[rollover:n][red] % \definecolor[rollover:r][green] % \definecolor[rollover:d][blue] \definepalet [rollover] [n=red, r=green, d=blue] \newinteger\c_scrn_rollbutton_n_button \newinteger\c_scrn_rollbutton_n_symbol \permanent\def\lastrollbuttonindex{\the\c_scrn_rollbutton_n_button} \setupfield [rollbutton] [\c!frame=\v!off, \c!offset=\v!overlay] \let\scrn_rollbutton_symbol\relax \def\scrn_rollbutton_symbol_m {\scrn_rollbutton_symbol_indeed \interactionmenuparameter \inheritedinteractionmenuframed \setinteractionmenuparameter \useinteractionmenustyleandcolor} \def\scrn_rollbutton_symbol_b {\scrn_rollbutton_symbol_indeed \buttonparameter \inheritedbuttonframed \setbuttonparameter \usebuttonstyleandcolor} \permanent\tolerant\protected\def\rollbutton[#tag]#spacer[#S#settings]#:#text[#reference]% {\dontleavehmode \bgroup \global\advanceby\c_scrn_rollbutton_n_button\plusone \global\advanceby\c_scrn_rollbutton_n_symbol\plusone \ifparameter#tag\or \ifparameter#settings\or \edef\currentinteractionmenu{#tag}% \setupcurrentinteractionmenu[#settings]% \let\scrn_rollbutton_symbol\scrn_rollbutton_symbol_m \orelse\ifhastok={#tag}% \lettonothing\currentbutton \setupcurrentbutton[#tag]% \let\scrn_rollbutton_symbol\scrn_rollbutton_symbol_b \else \edef\currentinteractionmenu{#tag}% \let\scrn_rollbutton_symbol\scrn_rollbutton_symbol_m \fi \else \let\scrn_rollbutton_symbol\scrn_rollbutton_symbol_b \fi % todo: share symbols, tricky since different dimensions (maybe \unique...) \definesymbol[rollsymbol:\the\c_scrn_rollbutton_n_symbol:n][\scrn_rollbutton_symbol{n}{#text}]% \definesymbol[rollsymbol:\the\c_scrn_rollbutton_n_symbol:r][\scrn_rollbutton_symbol{r}{#text}]% \definesymbol[rollsymbol:\the\c_scrn_rollbutton_n_symbol:d][\scrn_rollbutton_symbol{d}{#text}]% \definefield [rollbutton:\the\c_scrn_rollbutton_n_button][push][rollbutton] [rollsymbol:\the\c_scrn_rollbutton_n_symbol:n,% rollsymbol:\the\c_scrn_rollbutton_n_symbol:r,% rollsymbol:\the\c_scrn_rollbutton_n_symbol:d]% \fitfield [rollbutton:\the\c_scrn_rollbutton_n_button]% [\c!clickout={#reference}]% \egroup} \protected\def\scrn_rollbutton_symbol_indeed#getparameter#inheritedframed#setparameter#usestyleandcolor#what#text% {\definecolor[rollover][rollover:#what]% \ifcstok{#getparameter\c!alternative}\v!hidden \expandafter\phantom \else \expandafter\hbox \fi \bgroup #setparameter\c!framecolor {rollover}% #setparameter\c!backgroundcolor{rollover}% #setparameter\c!color {rollover}% #inheritedframed{#usestyleandcolor\c!style\c!color{#text}}% \egroup} %D We plug into the menu system \permanent\protected\def\scrn_menu_rob_start[#reference]#text\stoprob {\starttxt\rollbutton[\currentinteractionmenu]{\ignorespaces#text\unskip}[#reference]\stoptxt} \permanent\protected\def\scrn_menu_rob_direct[#reference]#text\\ {\scrn_menu_rob_start[#reference]#text\stoprob} \aliased\let\startrob\relax % maybe mutable \aliased\let\stoprob \relax % maybe mutable \aliased\let\rob \relax % maybe mutable \appendtoks \enforced\let\startrob\scrn_menu_rob_start \enforced\let\stoprob \relax \enforced\let\rob \scrn_menu_rob_direct \to \everysetmenucommands %D Signing: %D %D \starttyping %D \setupinteraction[state=start] %D %D \definefield[signature][signed] %D %D \starttext %D %D \defineoverlay[signature][my signature] %D %D \startTEXpage[offset=1ts] %D sign: \inframed %D [background=signature] %D {\fieldbody[signature][width=3cm,option=hidden]} %D \stopTEXpage %D %D \stoptext %D \stoptyping %D %D after processing: %D %D \starttyping %D mtxrun --script pdf --sign --certificate=somesign.pem --password=test --uselibrary somefile %D mtxrun --script pdf --verify --certificate=somesign.pem --password=test --uselibrary somefile %D \stoptyping \protect \endinput