%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. % There is still some leftover code from mkii, where we need to % be sparse with hash entries and so have a somewhat complex % setup mechanism. % 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 %D out of memory with thousands of fields, which we happen to need at %D that time. In \MKIV\ we can store some data at the \LUA\ end and %D use a somewhat slower but quite okay inheritance mechanism. For %D this reason we now have split definitions, although the old method %D is still somewhat supported. The clone and copy commands are %D somewhat obsolete for several reasons: we can now use inheritance %D and autocloning has been supported for a while. In most cases %D cloning (especially with check boxes) the acrobat browser is not %D stable enough with respect to appearance 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 %D can be set. %D %D Because there are persistent problems with acrobat rendering %D associated appearance streams (some messy /MK interferende) we %D also support native (built-in dingbat) symbols: check, circle, %D 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 %D that we want \FDF\ or \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 \appendtoks \iflocation \clf_exportformdata{\formsparameter\c!export}% \fi \to \everystoptext %D We need to initialize symbols in a special way so that they %D can be used as rendering for a widget. \unexpanded\def\presetfieldsymbols[#list]% slow {\processcommacommand[#list]\scrn_symbols_preset} \def\scrn_symbols_preset#set% {\processcommalist[#set]\scrn_symbols_preset_indeed}% \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 \let\dosetfieldsymbol\scrn_symbols_preset_indeed \def\dogetfieldsymbol#tag% {\getobject{SYM}{#tag}} \unexpanded\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}% \ifx\currentfieldbodycategory\empty \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 \ifx\currentfieldbodyparent\empty \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 \unexpanded\def\fieldbody {\dodoubleempty\scrn_field_body} \def\scrn_field_body[#tag][#settings]% {\iflocation \hbox\bgroup \edef\currentfieldbody{#tag}% \ifsecondargument \setupcurrentfieldbody[#settings]% \fi \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}% \ifx\currentfieldframecolor\empty\else \getcolorattributevalue\currentfieldframecolor\currentfieldframecolorvalue % == \edef\currentfieldframecolorvalue{\thecolorattribute\currentfieldframecolor}% \fi \edef\currentfieldbackgroundcolor{\fieldbodyparameter\c!fieldbackgroundcolor}% \ifx\currentfieldbackgroundcolor\empty\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 \ifx\currentfieldbackgroundcolor\empty \else backgroundcolor {\currentfieldbackgroundcolor}% backgroundcolorvalue \numexpr\currentfieldbackgroundcolorvalue\relax \fi \ifx\currentfieldframecolor\empty \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] \unexpanded\def\definefieldbodyset {\dodoubleempty\scrn_field_define_set} \def\scrn_field_define_set[#tag][#list]% {\clf_definefieldset{#tag}{#list}} \let\dodefinefieldset\definefieldbodyset % compatibility %D A few testing macros: \def\doifelsefieldbody #tag{\clf_doifelsefieldset{#tag}} \def\doifelsefieldcategory#tag{\clf_doifelsefieldcategory{#tag}} \let\doiffieldbodyelse \doifelsefieldbody \let\doiffieldcategoryelse\doifelsefieldcategory \let\doiffieldelse \doifelsefieldbody % compatibility / will be dropped \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 %D achieve the same. \unexpanded\def\definefield {\doquintupleempty\scrn_field_define_field} \unexpanded\def\definesubfield{\dotripleempty \scrn_field_define_subfield} \unexpanded\def\clonefield {\doquadrupleempty\scrn_field_clone_field} \unexpanded\def\copyfield {\dodoubleempty \scrn_field_copy_field} \let\definemainfield\definefield % obsolete ! \def\scrn_field_define_field[#tag][#type][#category][#values][#default]% {\definefieldbody[#tag][\c!type=#type,\c!category=#category,\c!values={#values},\c!default={#default}]} \def\scrn_field_define_subfield[#tag][#category][#values]% {\definefieldbody[#tag][\c!type=sub,\c!category=#category,\c!values={#values}]} \def\scrn_field_clone_field[#parent][#tag][#category][#values]% {\definefieldbody[#tag][#parent][\c!category=#category,\c!values={#values}]} \def\scrn_field_copy_field[#parent][#tag]% {\definefieldbody[#tag][#parent]} %D We hook fields into the (viewer based) layering mechanism %D (implemented as properties). \appendtoks \let\currentfieldcategory\empty \doifelse{\interactionparameter\c!fieldlayer}\v!auto {\setupcurrentfieldcategory[\c!fieldlayer=\currentviewerlayer]}% {\setupcurrentfieldcategory[\c!fieldlayer=]}% \to \everysetupinteraction \setupinteraction [\c!fieldlayer=\v!auto] % auto by default %D The \type {\fieldbody} is the more bare one. One step further goes %D \type {\fitfield}, in fact it (now) uses a dedicated instance of %D framed: \type {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=] \unexpanded\def\fitfield {\dodoubleempty\scrn_field_fit} \def\scrn_field_fit[#tag][#settings]% {\iflocation \begingroup \edef\currentdefaultfieldvalue{\clf_getdefaultfieldvalue{#tag}}% \setbox\b_scrn_field_fit_symbol\hbox{\symbol[\currentdefaultfieldvalue]}% \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 %D 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} \unexpanded\def\setupfield {\doquintupleempty\scrn_field_setup_field} \unexpanded\def\setupfields{\doquadrupleempty\scrn_field_setup_fields} \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 \def\scrn_field_setup_field[#tag][#variant][#totalsettings][#labelsettings][#fieldsettings]% {\iffifthargument \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]% \else\iffourthargument \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]% \else\ifthirdargument \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]% \else\ifsecondargument \definefieldcategory[#tag][\s!parent=\??fieldcontent#tag,#variant]% \setupfieldtotalframed [#tag][\s!parent=\??fieldtotal]% \setupfieldlabelframed [#tag][\s!parent=\??fieldlabel]% \setupfieldcontentframed[#tag][\s!parent=\??fieldcontent,#variant]% \fi\fi\fi\fi} \def\scrn_field_setup_fields[#variant][#totalsettings][#labelsettings][#fieldsettings]% {\iffourthargument \setupfieldtotalframed [\c!alternative={#variant},#totalsettings]% \setupfieldlabelframed [#labelsettings]% \setupfieldcontentframed[#fieldsettings]% \else\ifthirdargument \setupfieldtotalframed [#variant]% \setupfieldlabelframed [#totalsettings]% \setupfieldcontentframed[#labelsettings]% \else\ifsecondargument \setupfieldtotalframed [#variant]% \setupfieldcontentframed[#totalsettings]% \else \setupfieldtotalframed [#variant]% \fi\fi\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 \unexpanded\def\field {\dodoubleempty\scrn_field_direct} \def\scrn_field_direct[#tag][#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}}% \ifx\currentfieldlabel\empty \let\currentfieldlabel\currentfieldbody \fi \ifx\currentfieldcategory\empty \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) \doifnothing{\fieldcontentframedparameter\c!height} {\ifconditional\fieldisvertical \setfieldcontentframedparameter\c!height{6ex}% \else\ifconditional\fieldishorizontal \setfieldcontentframedparameter\c!height{\vsize}% \else \setfieldcontentframedparameter\c!height{2cm}% \fi\fi}% \doifnothing{\fieldcontentframedparameter\c!width} {\ifconditional\fieldisvertical \setfieldcontentframedparameter\c!width{\hsize}% \else\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 {\setfalse\fieldlabelshown \setfalse\fieldframeshown \setfalse\fieldishorizontal \setfalse\fieldisvertical \normalexpanded{\processallactionsinset[\fieldtotalframedparameter\c!alternative]} [ \v!reset=>\setfalse\fieldlabelshown \setfalse\fieldframeshown \setfalse\fieldishorizontal \setfalse\fieldisvertical, \v!label=>\settrue\fieldlabelshown, \v!frame=>\settrue\fieldframeshown, \v!horizontal=>\settrue\fieldishorizontal, \v!vertical=>\settrue\fieldisvertical]% \ifconditional\fieldisvertical \setupfieldtotalframed[\c!distance=\zeropoint,\c!inbetween=\vskip\d_framed_local_offset,\c!align=\v!right,\c!width=20em]% \else\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\fi \setupfieldtotalframed[\c!n=,\c!before=,\c!after=\vss,\c!style=,\c!color=]} %D Common stuff (obsolete) \newcount\c_scrn_field_system_n \def\currentsystemfield{sys::\number\c_scrn_field_system_n} \unexpanded\def\nextsystemfield {\global\advance\c_scrn_field_system_n\plusone} %D \CONTEXT\ had tooltips right from the moment that it %D supported fields. Due to the at that moment somewhat %D limited \PDF\ specification, they were implemented %D using \JAVASCRIPT, but nowadays more kind of actions %D are supported, so we can do without. The \MKIV\ version %D also supports definition of tooltips and 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 \newcount\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 \setuevalue\currenttooltip{\scrn_tooltip_direct{\currenttooltip}}% \to \everydefinetooltip \unexpanded\def\scrn_tooltip_direct#tag% {\def\currenttooltip{#tag}% \doifelselocation {\dosingleempty\scrn_tooltip_indeed} {\dosingleempty\scrn_tooltip_ignore}} \def\scrn_tooltip_ignore[#settings]#anchortext#tiptext% {#anchortext} \def\scrn_tooltip_indeed[#settings]#anchortext#tiptext% a more modern aproach (push buttons) {\dontleavehmode \hbox \bgroup \dontcomplain \global\advance\c_scrn_tooltip_n\plusone \edef\currenttooltipname{tooltip:\number\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 {\lettooltipparameter\c!location\empty \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\currenttooltiplocation{\tooltipparameter\c!location}% \ifx\currenttooltiplocation\v!left \hsmashed{\hskip\wd\b_scrn_tooltip_anchor\llap{\box\b_scrn_tooltip_text}}% \else\ifx\currenttooltiplocation\v!middle \hsmashed to \wd\b_scrn_tooltip_anchor{\hss\box\b_scrn_tooltip_text\hss}% \else \hsmashed{\box\b_scrn_tooltip_text}% \fi\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 %D fieldstacks are used so we 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} \unexpanded\def\definefieldstack {\dotripleargument\scrn_fieldstack_define} \def\scrn_fieldstack_define[#tag][#symbols][#settings]% {\ifcsname\??fieldstack#tag\endcsname % already done \else %setgvalue{\??fieldstack#tag}{\scrn_fieldstack_construct[#tag][#symbols][#settings]}% \setxvalue{\??fieldstack#tag}{\scrn_fieldstack_construct[#tag][#symbols][\normalunexpanded{#settings}]}% \fi} \unexpanded\def\fieldstack {\dotripleempty\scrn_fieldstack_direct} \def\scrn_fieldstack_direct[#tag][#symbols][#settings]% {\ifsecondargument \scrn_fieldstack_define[#tag][#symbols][#settings]% \fi \csname\??fieldstack#tag\endcsname} \newbox\b_scrn_fieldstack_box \definesymbol[\s!empty][] \def\scrn_fieldstack_add#tag#settings#symbol% {\advance\scratchcounter\plusone \edef\currentfieldstackname{#tag:\number\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]}} \unexpanded\def\scrn_fieldstack_construct[#tag][#symbols][#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 \newcount\c_scrn_rollbutton_n \unexpanded\def\overlayrollbutton {\dodoubleargument\scrn_rollbutton_overlay} \unexpanded\def\scrn_rollbutton_overlay[#regionin][#regionout]% {\iffirstargument \scrn_rollbutton_overlay_indeed[#regionin][#regionout]% \else \expandafter\scrn_rollbutton_overlay_indeed \fi} % \def\scrn_rollbutton_overlay_indeed#regionin#regionout% % {\iflocation % \bgroup % \global\advance\c_scrn_rollbutton_n\plusone % \definesymbol % [rollbutton:\number\c_scrn_rollbutton_n] % [{\framed[\c!frame=\v!off,\c!width=\overlaywidth,\c!height=\overlayheight]{}}]% % \definefieldbody % [rollbutton:\number\c_scrn_rollbutton_n] % [\c!type=push, % \c!regionin={#regionin}, % \c!regionout={#regionout}, % \c!values=\currentsystemfield, % \c!default=\currentsystemfield]% % \fitfield[\currentsystemfield]% % \egroup % \fi} \def\scrn_rollbutton_overlay_indeed#regionin#regionout% {\iflocation \bgroup \global\advance\c_scrn_rollbutton_n_button\plusone \global\advance\c_scrn_rollbutton_n_symbol\plusone \definesymbol [rollsymbol:\number\c_scrn_rollbutton_n_symbol] [{\framed[\c!frame=\v!off,\c!width=\overlaywidth,\c!height=\overlayheight]{}}]% % \definefieldbody % [rollbutton:\number\c_scrn_rollbutton_n_button] % [\c!type=push, % \c!values=rollsymbol:\number\c_scrn_rollbutton_n_symbol, % \c!default=rollsymbol:\number\c_scrn_rollbutton_n_symbol]% % \fitfield % [rollbutton:\number\c_scrn_rollbutton_n_button]% % [\c!regionin={#regionin}, % \c!regionout={#regionout}]% % \definefield [rollbutton:\number\c_scrn_rollbutton_n_button][push][rollbutton] [rollsymbol:\number\c_scrn_rollbutton_n_symbol]% \fitfield [rollbutton:\number\c_scrn_rollbutton_n_button]% [\c!regionin={#regionin},\c!regionout={#regionout}]% % \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 \newcount\c_scrn_pushbutton_n \unexpanded\def\definepushbutton % name optional setup {\dodoubleempty\scrn_pushbutton_define} \def\scrn_pushbutton_define[#tag][#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\advance\c_scrn_pushbutton_n\plusone \setupfield [pushbutton]% [\c!frame=\v!overlay,% \c!offset=\v!overlay,% \c!clickout={#reference},% #settings]% \definefield [pushbutton:\number\c_scrn_pushbutton_n]% [push]% [pushbutton]% [pushsymbol:#tag:n,pushsymbol:#tag:r,pushsymbol:#tag:d]% \fitfield [pushbutton:\number\c_scrn_pushbutton_n]% \egroup} \unexpanded\def\definepushsymbol {\dotripleargument\scrn_pushsymbol_define} \def\scrn_pushsymbol_define[#tag][#variant]% [#reference] {\definesymbol[pushsymbol:#tag:#variant]} \def\pushbutton {\dodoubleargument\scrn_pushbutton_direct} \def\scrn_pushbutton_direct[#tag][#variant]% {\executeifdefined{pushbutton:#tag}\gobbleoneargument{#variant}} %D We plug into the menu system \unexpanded\def\scrn_menu_psh_start[#reference]#text\stoppsh {\starttxt\pushbutton[\currentinteractionmenu][#reference]\stoptxt} \unexpanded\def\scrn_menu_psh_direct[#reference]#text\\ {\scrn_menu_psh_start[#reference]\stoprob} \appendtoks \let\startpsh\scrn_menu_psh_start \let\stoppsh \relax \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] \newcount\c_scrn_rollbutton_n_button \newcount\c_scrn_rollbutton_n_symbol \def\lastrollbuttonindex{\the\c_scrn_rollbutton_n_button} \unexpanded\def\rollbutton {\dodoubleempty\scrn_rollbutton} \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} \setupfield [rollbutton] [\c!frame=\v!off, \c!offset=\v!overlay] \def\scrn_rollbutton[#tag][#settings]#text[#reference]% {\dontleavehmode \bgroup \global\advance\c_scrn_rollbutton_n_button\plusone \global\advance\c_scrn_rollbutton_n_symbol\plusone \iffirstargument \ifsecondargument \edef\currentinteractionmenu{#tag}% \setupcurrentinteractionmenu[#settings]% \let\scrn_rollbutton_symbol\scrn_rollbutton_symbol_m \else \doifelseassignment{#tag} {\let\currentbutton\empty \setupcurrentbutton[#tag]% \let\scrn_rollbutton_symbol\scrn_rollbutton_symbol_b}% {\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:\number\c_scrn_rollbutton_n_symbol:n][\scrn_rollbutton_symbol{n}{#text}]% \definesymbol[rollsymbol:\number\c_scrn_rollbutton_n_symbol:r][\scrn_rollbutton_symbol{r}{#text}]% \definesymbol[rollsymbol:\number\c_scrn_rollbutton_n_symbol:d][\scrn_rollbutton_symbol{d}{#text}]% \definefield [rollbutton:\number\c_scrn_rollbutton_n_button][push][rollbutton] [rollsymbol:\number\c_scrn_rollbutton_n_symbol:n,% rollsymbol:\number\c_scrn_rollbutton_n_symbol:r,% rollsymbol:\number\c_scrn_rollbutton_n_symbol:d]% \fitfield [rollbutton:\number\c_scrn_rollbutton_n_button]% [\c!clickout={#reference}]% \egroup} \unexpanded\def\scrn_rollbutton_symbol_indeed#getparameter#inheritedframed#setparameter#usestyleandcolor#what#text% {\definecolor[rollover][rollover:#what]% \doifelse{#getparameter\c!alternative}\v!hidden\phantom\hbox {#setparameter\c!framecolor {rollover}% #setparameter\c!backgroundcolor{rollover}% #setparameter\c!color {rollover}% #inheritedframed{#usestyleandcolor\c!style\c!color{#text}}}} %D We plug into the menu system \unexpanded\def\scrn_menu_rob_start[#reference]#text\stoprob {\starttxt\rollbutton[\currentinteractionmenu]{\ignorespaces#text\unskip}[#reference]\stoptxt} \unexpanded\def\scrn_menu_rob_direct[#reference]#text\\ {\scrn_menu_rob_start[#reference]#text\stoprob} \appendtoks \let\startrob\scrn_menu_rob_start \let\stoprob \relax \let\rob \scrn_menu_rob_direct \to \everysetmenucommands \protect \endinput