%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}

\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:

\def\setupinteractionmenu
  {\dodoubleargument\dosetupinteractionmenu}

\def\dosetupinteractionmenu[#1][#2]%
  {\def\docommand##1{\getparameters[\??am##1][#2]}%
   \processcommalist[#1]\docommand}

\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}

% \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!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!distance=\bodyfontsize, % 12pt
   \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!distance=\bodyfontsize, % 12pt
   \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 ]

\def\placeleftedgetextblock % Is \hss/\hsize really needed here? (check outer level and settings)
  {\hbox to \leftedgewidth{\hsize\leftedgewidth\hss\interactionmenus[\v!left]}}

\def\placerightedgetextblock % Is \hss/\hsize really needed here? (check outer level and settings)
  {\hbox to \rightedgewidth{\hsize\rightedgewidth\interactionmenus[\v!right]\hss}}

\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}}

\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
