%D \module %D [ file=scrn-bar, % was part of scrn-int %D version=1995.01.01, %D title=\CONTEXT\ Core Macros, %D subtitle=Menus, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA / Hans Hagen \& Ton Otten}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. \writestatus{loading}{ConTeXt Screen Macros / Menus} \unprotect % \startinteractionmenu[rechts] % \but [eerste] eerste \\ % \txt hello world \\ % \but [tweede] tweede \\ % \nop \\ % \but [tweede] tweede \\ % \rul whow \\ % \but [tweede] tweede \\ % \raw hello world \\ % \but [tweede] tweede \\ % \com \vfill \\ % \but [derde] derde \\ % \stopinteractionmenu % \setupinteraction[menu=on,state=start] % % \defineinteractionmenuclass[test] [vertical] % \defineinteractionmenuclass[another][horizontal] % % \defineinteractionmenu[test] [left][state=start,width=4cm] % \defineinteractionmenu[another][top] [state=start,height=1cm] % % \startinteractionmenu[test] % \but [firstpage] test-a \\ % \but [nextpage] test-b \\ % \stopinteractionmenu % % \startinteractionmenu[another] % \but [firstpage] test-a \\ % \but [nextpage] test-b \\ % \stopinteractionmenu % % \setupheadertexts[{\interactionmenu[another]}] % % \starttext % % test \interactionmenu[test] \page % test \interactionmenu[test] \page % % \stoptext % ja : kader/achtergrond met tekst % leeg : kader/achtergrond maar geen tekst % nee : alleen ruimte reserveren % geen : helemaal weglaten % % \setupinteractionmenu[right][samepage=yes, unknownreference=yes] % \setupinteractionmenu[right][samepage=empty,unknownreference=empty] % \setupinteractionmenu[right][samepage=no, unknownreference=no] % \setupinteractionmenu[right][samepage=none, unknownreference=none] % % \startinteractionmenu[right] % \but [firstpage] first \\ % \but [lastpage] last \\ % \but [somepage] crap \\ % \stopinteractionmenu %D Define menus: \def\setmenuparameter#1#2#3{\@EA\def\csname\??am#1#2\endcsname{#3}} \def\letmenuparameter #1#2{\@EA\let\csname\??am#1#2\endcsname} \def\menuparameter #1{\csname\domenuparameter{\??am\currentmenu}#1\endcsname} \def\namedmenuparameter#1#2{\csname\domenuparameter{\??am #1}#2\endcsname} \def\menuparameterhash #1{\domenuparameterhash {\??am\currentmenu}#1} \def\domenuparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\domenuparentparameter \csname#1\s!parent\endcsname#2\fi} \def\domenuparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\domenuparentparameterhash\csname#1\s!parent\endcsname#2\fi} \def\domenuparentparameter #1#2{\ifx#1\relax\s!empty\else\domenuparameter #1#2\fi} \def\domenuparentparameterhash#1#2{\ifx#1\relax \else\domenuparameterhash#1#2\fi} \unexpanded\def\defineinteractionmenu {\dotripleempty\dodefineinteractionmenu} \def\dodefineinteractionmenu[#1][#2][#3]% [name] [location] [settings] {\ifsecondargument \ifcsname\??am:\c!list:#2\endcsname \else \letvalue{\??am:\c!list:#2}\empty \fi \normalexpanded{\noexpand\addtocommalist{#1}\@EA\noexpand\csname\??am:\c!list:#2\endcsname}% \setvalue{\@@dodolistelement#1}{\def\dosomelistelement{\dodomenulistelement{#1}}}% \ifthirdargument \presetlocalframed[\??am#1]% \doifassignmentelse{#3} {\doifelse{#1}{#2} {\getparameters[\??am#1][\c!location=#2,\c!menu=,\s!parent=\??am,#3]} {\getparameters[\??am#1][\c!location=#2,\c!menu=,\s!parent=\??am#2,#3]}}% {\doifelsenothing{#3} {\getparameters[\??am#1][\c!location=#2,\c!menu=,\s!parent=\??am]} {\getparameters[\??am#1][\c!location=#2,\c!menu=,\s!parent=\??am#3]}}% \else \getparameters[\??am#1][\c!location=#2,\c!menu=,\s!parent=\??am#2]% \fi \else \getparameters[\??am#1][\s!parent=\??am]% simple cloning \fi} \def\currentmenulist{\ifcsname\??am:\c!list:\currentmenu\endcsname\csname\??am:\c!list:\currentmenu\endcsname\fi} %D Setup menus: \unexpanded\def\setupinteractionmenu {\dodoubleargument\dosetupinteractionmenu} \def\dosetupinteractionmenu[#1][#2]% {\def\docommand##1{\getparameters[\??am##1][#2]}% \processcommalist[#1]\docommand} \unexpanded\def\setupinteractionmenus[#1]% {\getparameters[\??am][#1]} %D Fill menus: \normalexpanded{\long\def\expandafter\noexpand\csname\e!start\v!interactionmenu\endcsname[#1]#2\expandafter\noexpand\csname\e!stop\v!interactionmenu\endcsname}% {\long\setmenuparameter{#1}\c!menu{\dointeractionmenu{#1}{#2}}} \def\resetinteractionmenu[#1]% {\letmenuparameter{#1}\c!menu\empty} %D Check if menus permitted: \newif\iflocationmenupermitted \def\testinteractionmenu {\iflocation \doifelse\@@iamenu\v!on {\doifelse{\menuparameter\c!state}\v!start {\global\locationmenupermittedtrue} {\global\locationmenupermittedfalse}} {\global\locationmenupermittedfalse}% \else \global\locationmenupermittedfalse \fi} %D Placement of menus: \def\interactionmenus[#1]% location {\iflocation \csname\??am:\c!menu:#1\endcsname \fi} % \unexpanded\def\defineinteractionmenuclass % {\dodoubleargument\dodefineinteractionmenuclass} % % \def\dodefineinteractionmenuclass[#1][#2]% tag hori|veri % {\doifelse{#2}\v!vertical % {\setvalue{\??am:\c!menu:#1}{\verticalinteractionmenu {#1}{\getvalue{\??am#1\c!width }}}} % {\setvalue{\??am:\c!menu:#1}{\horizontalinteractionmenu{#1}{\getvalue{\??am#1\c!height}}}}} % % \defineinteractionmenuclass[\v!left ][\v!horizontal] % \defineinteractionmenuclass[\v!right ][\v!horizontal] % \defineinteractionmenuclass[\v!top ][\v!vertical] % \defineinteractionmenuclass[\v!bottom][\v!vertical] \setvalue{\??am:\c!menu :\v!left }{\horizontalinteractionmenu\v!left \leftedgewidth } \setvalue{\??am:\c!menu :\v!right }{\horizontalinteractionmenu\v!right \rightedgewidth} \setvalue{\??am:\c!menu :\v!top }{\verticalinteractionmenu \v!top \topheight } \setvalue{\??am:\c!menu :\v!bottom}{\verticalinteractionmenu \v!bottom\bottomheight } \setvalue{\??am:\c!command:\v!right }{\@@amvbox{}\rightedgewidth} \setvalue{\??am:\c!command:\v!left }{\@@amvbox{}\leftedgewidth } \setvalue{\??am:\c!command:\v!top }{\@@amhbox{}\topheight } \setvalue{\??am:\c!command:\v!bottom}{\@@amhbox{}\bottomheight } \def\dointeractionmenu#1#2% {\edef\currentmenu{#1}% \getvalue{\??am:\c!command:\menuparameter\c!location}\currentmenu{#2}} \unexpanded\def\interactionmenu[#1]% {\def\currentmenu{#1}% \menuparameter\c!menu} \newdimen \intermenudistance \newdimen \finalmenuwidth \newdimen \finalmenuheight \newcounter\currentamposition % better \currentmenuposition \newtoks \everysetmenucommands \def\horizontalinteractionmenu#1#2% location vhsize before/after {\ifdim#2>\zeropoint \edef\currentmenu{#1}% \finalmenuwidth#2\relax \horizontalinteractionmenuindeed \fi} \def\verticalinteractionmenu#1#2% {\ifdim#2>\zeropoint \edef\currentmenu{#1}% \finalmenuheight#2\relax \verticalinteractionmenuindeed \fi} \def\horizontalinteractionmenuindeed {\global\intermenudistance\zeropoint \setbox\scratchbox\hbox {\processcommacommand[\currentmenulist]\somehorizontalinteractionmenu}% \wd\scratchbox\finalmenuwidth\relax \box\scratchbox} \def\verticalinteractionmenuindeed {\global\intermenudistance\zeropoint \setbox\scratchbox\vbox {\processcommacommand[\currentmenulist]\someverticalinteractionmenu}% \ht\scratchbox\finalmenuheight \dp\scratchbox\zeropoint \box\scratchbox} \def\somehorizontalinteractionmenu#1% {\begingroup \edef\currentmenu{#1}% \doifnot{\menuparameter\c!state}\v!none {\hskip\intermenudistance \setbox\scratchbox\hbox to \finalmenuwidth {\menuparameter\c!left \interactionmenu[#1]% \menuparameter\c!right}% \doifelse{\menuparameter\c!distance}\v!overlay {\global\intermenudistance\zeropoint \wd\scratchbox\zeropoint}% {\global\intermenudistance\menuparameter\c!distance}% \box\scratchbox}% \endgroup} \def\someverticalinteractionmenu#1% {\begingroup \edef\currentmenu{#1}% \doifnot{\menuparameter\c!state}\v!none {\vskip\intermenudistance \setbox\scratchbox\vbox to \finalmenuheight {\menuparameter\c!before \interactionmenu[#1]% \menuparameter\c!after}% \doifelse{\menuparameter\c!distance}\v!overlay {\global\intermenudistance\zeropoint \offinterlineskip \dp\scratchbox\zeropoint \ht\scratchbox\zeropoint}% {\global\intermenudistance\menuparameter\c!distance}% \box\scratchbox}% \endgroup} % don't change skipping, this one works! \showcomposition removed \def\@@amhbox#1#2#3#4% #1 obsolete, #3 is redundant {\edef\currentmenu{#3}% \testinteractionmenu \iflocationmenupermitted \begingroup \forgetall \scratchdimen\dimexpr\makeupwidth+\pagebackgroundhoffset*2-\menuparameter\c!leftoffset-\menuparameter\c!rightoffset\relax \setbox\scratchbox\hbox to \scratchdimen {\executeamboxcommands{#3}{#4}\c!left\c!middle\c!right}% \setbox\scratchbox\hbox{\dowholemenuposition{#3}{\box\scratchbox}}% cannot happen in previous due to align \wd\scratchbox\makeupwidth % geen \ht=#2 setting (yet) \hskip\dimexpr-\pagebackgroundhoffset+\menuparameter\c!leftoffset\relax \box\scratchbox \endgroup \fi} \def\@@amvbox#1#2#3#4% #1 obsolete, #3 is redundant {\edef\currentmenu{#3}% \testinteractionmenu \iflocationmenupermitted \bgroup \forgetall \scratchdimen\dimexpr\textheight+\pagebackgroundvoffset*2+\pagebackgrounddepth-\menuparameter\c!topoffset-\menuparameter\c!bottomoffset\relax \setbox\scratchbox\vbox to \scratchdimen {\restorestandardblank % todo: vspacing \hsize#2\relax \executeamboxcommands{#3}{#4}\c!before\c!inbetween\c!after}% % strange: when we mnake this a hbox the content disappears \setbox\scratchbox\vbox{\dowholemenuposition{#3}{\box\scratchbox}}% cannot happen in previous due to align \setbox\scratchbox\vbox {\ht\scratchbox\zeropoint \vskip\dimexpr-\pagebackgroundvoffset+\menuparameter\c!topoffset\relax \box\scratchbox \vskip\pagebackgroundvoffset}% overbodig \ht\scratchbox\textheight \wd\scratchbox#2\relax \box\scratchbox \egroup \fi} \def\executeamboxcommands#1#2#3#4#5% {\begingroup \edef\currentmenu{#1}% \menuparameter#3\relax \setamboxcommands{#1}{#4}% \ignorespaces#2\unskip \menuparameter#5\relax \endgroup} \def\setamboxcommands#1#2% {\edef\currentmenu{#1}% \edef\betweenmenu{#2}% \doglobal\newcounter\currentamposition \the\everysetmenucommands} \def\addsomemenuitem#1% {\dontleavehmode \begingroup \ignorespaces#1\unskip\relax \ifconditional\skippedmenuitem \else \menuparameter\betweenmenu \fi \endgroup \ignorespaces} %D This can save complicated menu macros when one want to %D keep control over parts of a menu (i.e.\ turn them on and %D off). We could have achieved something similar with modes. \def\local@@ambox#1#2#3#4% don't change skipping, this one works! {\begingroup \edef\currentmenu{#3}% \iflocationmenupermitted \executeamboxcommands{#3}{#4}\c!before\c!inbetween\c!after \fi \endgroup} \def\includemenu[#1]% {\begingroup \edef\currentmenu{#1}% \doif{\menuparameter\c!state}\v!local {\letmenuparameter\currentmenu\c!state\v!start \let\@@amvbox\local@@ambox \let\@@amhbox\local@@ambox \menuparameter\c!menu}% \endgroup} %D The menu commands: % ja : kader/achtergrond met tekst % leeg : kader/achtergrond maar geen tekst % nee : alleen ruimte reserveren % geen : helemaal weglaten \newconditional\skippedmenuitem \newconditional\usemenuclick \def\dosetlocationboxcontent#1[#2]#3[#4]% to be checked {\global\setfalse\skippedmenuitem \setbox\locationbox\hbox{\localframed[#1][#2]{#3}}% \ifconditional\usemenuclick \gotobox{\box\locationbox}[#4]% \else \box\locationbox \fi} \def\dosetlocationboxempty#1[% {\dosetlocationboxcontent{#1}[\c!empty=\v!yes,} \def\dosetlocationboxno#1[% {\dosetlocationboxcontent{#1}[\c!empty=\v!yes,\c!frame=,\c!background=,} \def\dosetlocationboxnone#1[#2]#3[#4]% {\global\settrue\skippedmenuitem} % make two sub macros % \dosetfontattribute {#1}{#2}% % \dosetcolorattribute{#1}{#3}% \def\setlocationboxyes#1[#2]#3[#4]% needs to be split as the attr is not applicable to the box {\begingroup \settrue\usemenuclick \global\setfalse\skippedmenuitem \attribute\referenceattribute\attributeunsetvalue \doifreferencefoundelse{#4} {\analyzecurrentreference % we need to act on the state \ifcase\referencepagestate % something else than a page reference \ctxlua{jobreferences.injectcurrentset(nil,nil)}% \hbox attr \referenceattribute \lastreferenceattribute {\localframed[#1][#2]{#3}}% \else\ifcase\csname\??am:\c!location:\menuparameter\c!samepage\endcsname\relax % yes: same page or not ... todo \ctxlua{jobreferences.injectcurrentset(nil,nil)}% \ifnum\referencepagestate=\plusone % same page \hbox attr \referenceattribute \lastreferenceattribute {\localframed[#1][#2,\c!color=\menuparameter\c!contrastcolor]{#3}}% \else % elsewhere \hbox attr \referenceattribute \lastreferenceattribute {\localframed[#1][#2]{#3}}% \fi \or % empty but frame: no click \localframed[#1][\c!empty=\v!yes,#2]{#3}% \or % empty no frame: no \localframed[#1][\c!empty=\v!yes,\c!frame=,\c!background=,#2]{#3}% \or % nothing at all \global\settrue\skippedmenuitem \fi\fi}% {\unknownreference{#4}% \ifcase\csname\??am:\c!location:\menuparameter\c!unknownreference\endcsname\relax \localframed[#1][#2]{#3}% \or \localframed[#1][\c!empty=\v!yes,#2]{#3}% \or \localframed[#1][\c!empty=\v!yes,\c!frame=,\c!background=,#2]{#1}% \or \global\skippedmenuitemtrue \fi}% \endgroup} \def\setlocationboxraw#1[#2]#3[#4]% {\localframed[#1][#2]{#3}} \def\setlocationnop#1[#2]#3% {\localframed[#1][#2]{#3}} \def\menu@raw[#1]#2\\% {\addsomemenuitem{\gotobox{\ignorespaces#2\unskip}[#1]}} \def\menu@but[#1]#2\\% {\addsomemenuitem{\domenuitemposition\currentmenu{#1}{\setlocationboxyes{\??am\currentmenu}[]{\ignorespaces#2\unskip}[#1]}}} \def\menu@got[#1]#2\\% {\addsomemenuitem{\setlocationboxyes{\??am\currentmenu}[\c!frame=\v!off,\c!background=]{\ignorespaces#2\unskip}[#1]}} \def\menu@nop#1\\% {\addsomemenuitem{\setlocationboxraw{\??am\currentmenu}[\c!frame=\v!off,\c!background=,\c!empty=\v!yes]{\ignorespaces#1\unskip}[]}} \def\menu@txt#1\\% {\addsomemenuitem{\localframed[\??am\currentmenu][\c!frame=\v!off,\c!background=]{\ignorespaces#1\unskip}}} \def\menu@rul#1\\% {\addsomemenuitem{\localframed[\??am\currentmenu][]{\ignorespaces#1\unskip}}} \def\menu@com#1\\% {\ignorespaces#1\unskip\ignorespaces} \appendtoks \let\raw\menu@raw \let\but\menu@but \let\got\menu@got \let\nop\menu@nop \let\txt\menu@txt \let\rul\menu@rul \let\com\menu@com \to \everysetmenucommands \ifdefined\domenuitemposition \else \let\domenuitemposition \gobbletwoarguments \fi \ifdefined\dowholemenuposition \else \let\dowholemenuposition\gobbleoneargument \fi %D We also need an explicit position control some day. I'll %D do that when I need it. [The stacking order.] % [name] [location] % [name] [location] [pars] \expandafter\chardef\csname\??am:\c!location:\v!yes \endcsname\zerocount \expandafter\chardef\csname\??am:\c!location:\v!empty \endcsname\plusone \expandafter\chardef\csname\??am:\c!location:\v!no \endcsname\plustwo \expandafter\chardef\csname\??am:\c!location:\v!none \endcsname\plusthree \expandafter\chardef\csname\??am:\c!location:\v!normal \endcsname\plusone % default \expandafter\chardef\csname\??am:\c!location:\s!default\endcsname\plusone % default \expandafter\chardef\csname\??am:\c!location:\s!empty \endcsname\plusone % default \def\dodomenulistelement#1#2#3#4#5#6#7% {\addsomemenuitem{\domenuitemposition\currentmenu{internal(#3)}% {\setlocationboxyes{\??am\currentmenu}[]{\limitatetext{#5}{\namedlistparameter{#2}\c!maxwidth}{\unknown}}[internal(#3)]}}} \unexpanded\def\menubutton {\dodoubleempty\domenubutton} \def\domenubutton[#1]% {\iffirstargument \ifsecondargument \@EAEAEA\domenubuttonB \else \doifassignmentelse{#1} {\@EAEAEA\domenubuttonC} {\@EAEAEA\domenubuttonD}% \fi \else \@EA\domenubuttonA \fi[#1]} \def\domenubuttonA[#1][#2]#3[#4]{\setlocationboxyes\??bt[]{#3}[#4]} % normal button, no parameters \def\domenubuttonB[#1][#2]#3[#4]{\setlocationboxyes{\??am#1}[#2]{#3}[#4]} % menu button, with parameters \def\domenubuttonC[#1][#2]#3[#4]{\setlocationboxyes\??bt[#1]{#3}[#4]} % normal button, with parameters \def\domenubuttonD[#1][#2]#3[#4]{\setlocationboxyes{\??am#1}[]{#3}[#4]} % menu button, no parameters \def\menubox {\dodoubleempty\domenubox} \def\domenubox[#1][#2]#3% {\bgroup \let\setlocationboxyes\setlocationboxraw \domenubutton[#1][#2]#3[]% \egroup} % jammer, tussen/midden had erin gemoeten; \c!commando toevoegen \def\registermenucommand#1% {{\textonly\noindent#1\space}} % no math switching \def\doregistermenubuttons[#1][#2]% [menu id] [register] {\bgroup \ifsecondargument \setupinteractionmenu[#1][\c!unknownreference=\v!yes,\c!samepage=\v!yes]% \def\docommand##1{\registermenucommand{\menubutton[#1]{##1}[#2:##1]}}% \else \def\docommand##1{\registermenucommand{\button[\c!unknownreference=\v!yes,\c!samepage=\v!yes]{##1}[#1:##1]}}% \fi \handletokens abcdefghijklmnopqrstuvwxyz\with\docommand % moet anders \egroup} \def\registermenubuttons {\dodoubleempty\doregistermenubuttons} \defineinteractionmenu [\v!vertical] % we happen to know that this works out ok (just a setup set) \defineinteractionmenu [\v!horizontal] % we happen to know that this works out ok (just a setup set) \defineinteractionmenu [\v!right ] [\v!right ] [\v!vertical ] % we share a setup set \defineinteractionmenu [\v!left ] [\v!left ] [\v!vertical ] % we share a setup set \defineinteractionmenu [\v!top ] [\v!top ] [\v!horizontal] % we share a setup set \defineinteractionmenu [\v!bottom] [\v!bottom] [\v!horizontal] % we share a setup set \setupinteractionmenus [\c!offset=.25em, \c!position=\v!no, \c!frame=\v!on, \c!background=, \c!backgroundcolor=, \c!foregroundstyle=\menuparameter\c!style, \c!foregroundcolor=\menuparameter\c!color, \c!style=\@@iastyle, \c!color=\@@iacolor, \c!contrastcolor=\@@iacontrastcolor, \c!state=\v!start, \c!samepage=\v!yes, \c!unknownreference=\v!empty, \c!distance=\bodyfontsize, % 12pt \c!topoffset=\zeropoint, \c!bottomoffset=\zeropoint, \c!leftoffset=\zeropoint, \c!rightoffset=\zeropoint] \setupinteractionmenu [\v!vertical] % not really a menu [\c!before=, \c!after=\vfil, \c!inbetween=\blank, \c!left=\hss, \c!right=\hss, \c!height=\v!broad] \setupinteractionmenu [\v!horizontal] % not really a menu [\c!before=\vss, \c!after=\vss, \c!middle=\hfil, \c!width=\v!fit, \c!height=\v!broad] \setupinteractionmenu[\v!left ][\c!width=\leftedgewidth ] \setupinteractionmenu[\v!right ][\c!width=\rightedgewidth] % \setupinteractionmenu[\v!top ] [\c!height=\topheight ] % \setupinteractionmenu[\v!bottom] [\c!height=\bottomheight ] \unexpanded\def\placeleftedgetextblock % Is \hss/\hsize really needed here? (check outer level and settings) {\hbox to \leftedgewidth{\hsize\leftedgewidth\hss\interactionmenus[\v!left]}} \unexpanded\def\placerightedgetextblock % Is \hss/\hsize really needed here? (check outer level and settings) {\hbox to \rightedgewidth{\hsize\rightedgewidth\interactionmenus[\v!right]\hss}} \unexpanded\def\placetoptextblock {\vbox to \topheight {\vsize\topheight \csname\??tk\v!top\c!before\endcsname \interactionmenus[\v!top]% \csname\??tk\v!top\c!after\endcsname \kern\zeropoint}} \unexpanded\def\placebottomtextblock {\vbox to \bottomheight {\vsize\bottomheight \csname\??tk\v!bottom\c!before\endcsname \interactionmenus[\v!bottom]% \csname\??tk\v!bottom\c!after\endcsname \kern\zeropoint}} \ifdefined\leftedgetextcontent \appendtoks \iflocation\placeleftedgetextblock \hskip-\leftedgewidth \fi\to \leftedgetextcontent \appendtoks \iflocation\placerightedgetextblock \hskip-\rightedgewidth \fi\to \rightedgetextcontent \appendtoks \iflocation\placetoptextblock \vskip-\topheight \fi\to \toptextcontent \appendtoks \iflocation\placebottomtextblock \vskip-\bottomheight \fi\to \bottomtextcontent \fi %D Enable and disable menus \unknown\ obsolete: \def\gobbletwoparameters[#1][#2]{} \def\disableinteractionmenu{\dodoubleempty\gobbletwoparameters} \def\enableinteractionmenu {\dodoubleempty\gobbletwoparameters} \protect \endinput