# Move-around box in PDF display

I tried using the fancytooltips package and like it a lot. One thing that I could imagine would be nice is to have the entry showing up as a movable box instead of just a tooltip. (Sometimes the tooltip obscures other text.) Is this possible at all to implement? I mean it could take a lot of work, but if it's possible at all I'd like to look into it.

The examples and screenshots of fancytooltips can be found in this post. To quote from that post:

Both Gonzalo Medina and Audrey posted an excellent solution. But the things are simpler now. See the fancy-preview webpage - based on the new version of fancytooltips (May 2012), preview.sty and some bash scripts you get tooltips for bibliographic entries, theorems, definitions, displayed equations etc. automatically.

Small example and screenshots are attached.

\documentclass{article}
\usepackage{amsmath,amsthm}
\newtheorem{lemma}{Lemma}
\usepackage{hyperref} % Important!
\begin{document}

\begin{lemma}[Lemma from \cite{M}]\label{lemma}
If $k<0$, then
$$\label{eq:1} x^2+k<x^2$$
for every real number $x$.
\end{lemma}

Inequality \eqref{eq:1} in Lema \ref{lemma} can be proved easily. Is
more general than \cite[Theorem 3.4]{K}.

\begin{thebibliography}{9}
\bibitem[M]{M} Me: My book related to the problem (2006), 145 p.
% The new line is important!

\bibitem{K} Karl: Karl's paper published in some minor proceedings,
a local conferrence organized by his university (2005), 23--25.
% The new line is important!

\end{thebibliography}
\end{document}


Ref M

Ref 1

Equation (1)

Lemma 1.

• Just because many users (like me) might not be familiar with fancytooltips, could you add a MWE, perhaps even demonstrating the problematic overlap, and a picture of the output? Apr 6, 2013 at 17:00
• @doncherry Good point, I've just edited to add that! Apr 6, 2013 at 17:10
• Thanks! Perhaps you could even include (reproduce) it in this question? We kind of like to have everything in one place. Apr 6, 2013 at 17:20
• @doncherry Done! Apr 6, 2013 at 21:35

This would require hacking the fancytooltips package.

Since fancytooltips depends on packages which are not in TeXLive, I tried something on my own.

The tool-tip command defined below supports all common output drivers (LaTeX workflows):

• latex->dvips->ps2pdf (dvips must not be called with option -Ppdf!)
• latex->dvipdfmx
• xelatex, lualatex, pdflatex

The command

\tooltip[<link text colour>]{<link text>}[<tip box colour>]{<tip text>}


creates a tooltip that can be dragged around.

The colour arguments are optional and default to blue and yellow!20. Predefined colour names and colour expressions according to the colour-model of the xcolor package can be used. Ifhyperref is loaded, its colour setting for internal links (option linkcolor) is used as <link text colour>.

<link text> is breakable across line endings, except for the latex->dvips->ps2pdf workflow.

Multi-line <tip text> should be put into a \parbox or minipage.

\documentclass[a6paper,12pt]{scrbook}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% tooltips with LaTeX v. 2017/11/28
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%   \tooltip     --> draggable tip, visible on mouse-over, hidden on mouse-out
%
%   \tooltip*    --> draggable tip, toggle visiblity on mouse-over
%
%   \tooltip**   --> NON-draggable tip, visible on mouse-over, hidden on mouse-out
%
%   \tooltip***  --> NON-draggable tip, toggle visiblity on mouse-over
%
%   \tooltip**** --> NON-draggable tip, toggle visiblity on mouse-click (Evince!)
%
% Default link colour can be set with
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{pdfbase}[2017/03/16]
\usepackage{xparse,ocgbase}
\usepackage{xcolor,calc}
\usepackage{tikzpagenodes}
\usetikzlibrary{calc}

\ExplSyntaxOn
\let\tpPdfAnnot\pbs_pdfannot:nnnn\let\tpPdfLastAnn\pbs_pdflastann:
\let\tpAppendToFields\pbs_appendtofields:n
\def\tpPdfXform{\pbs_pdfxform:nnnnn{1}{1}{}{}}
\let\tpPdfLastXform\pbs_pdflastxform:
\ExplSyntaxOff

\makeatletter
\NewDocumentCommand{\tooltip}{%
}{{%
\leavevmode%
\IfBooleanT{#2}{%
%for variants with two and more stars, put tip box on a PDF Layer (OCG)
\ocgbase@new@ocg{tipOCG.\thetcnt}{%
/Print<</PrintState/OFF>>/Export<</ExportState/OFF>>%
}{false}%
\xdef\tpTipOcg{\ocgbase@last@ocg}%
%prevent simultaneous visibility of multiple non-draggable tooltips
}%
\IfBooleanTF{#4}{%
/Subtype/Link/Border[0 0 0]/A <</S/SetOCGState/State [/Toggle \tpTipOcg]>>
}{%
/Subtype/Screen%
/AA<<%
\IfBooleanTF{#3}{%
/E<</S/SetOCGState/State [/Toggle \tpTipOcg]>>%
}{%
\IfBooleanTF{#2}{%
/E<</S/SetOCGState/State [/ON \tpTipOcg]>>%
/X<</S/SetOCGState/State [/OFF \tpTipOcg]>>%
}{
\IfBooleanTF{#1}{%
/E<</S/JavaScript/JS(%
var fd=this.getField('tip.\thetcnt');%
if(typeof(click\thetcnt)=='undefined'){%
var click\thetcnt=false;%
var fdor\thetcnt=fd.rect;var dragging\thetcnt=false;%
}%
if(fd.display==display.hidden){%
fd.delay=true;fd.display=display.visible;fd.delay=false;%
}else{%
if(!click\thetcnt&&!dragging\thetcnt){fd.display=display.hidden;}%
if(!dragging\thetcnt){click\thetcnt=false;}%
}%
this.dirty=false;%
)>>%
}{%
/E<</S/JavaScript/JS(%
var fd=this.getField('tip.\thetcnt');%
if(typeof(click\thetcnt)=='undefined'){%
var click\thetcnt=false;%
var fdor\thetcnt=fd.rect;var dragging\thetcnt=false;%
}%
if(fd.display==display.hidden){%
fd.delay=true;fd.display=display.visible;fd.delay=false;%
}%
this.dirty=false;%
)>>%
/X<</S/JavaScript/JS(%
if(!click\thetcnt&&!dragging\thetcnt){fd.display=display.hidden;}%
if(!dragging\thetcnt){click\thetcnt=false;}%
this.dirty=false;%
)>>%
}%
/U<</S/JavaScript/JS(click\thetcnt=true;this.dirty=false;)>>%
/PC<</S/JavaScript/JS (%
var fd=this.getField('tip.\thetcnt');%
try{fd.rect=fdor\thetcnt;}catch(e){}%
fd.display=display.hidden;this.dirty=false;%
)>>%
/PO<</S/JavaScript/JS(this.dirty=false;)>>%
}%
}%
>>%
}%
}{{\color{#5}#6}}%
\sbox\tiptext{%
\IfBooleanT{#2}{%
\ocgbase@oc@bdc{\tpTipOcg}\ocgbase@open@stack@push{\tpTipOcg}}%
\fcolorbox{black}{#7}{#8}%
\IfBooleanT{#2}{\ocgbase@oc@emc\ocgbase@open@stack@pop\tpNull}%
}%
\edef\twd{\the\wd\tiptext}%
\edef\tht{\the\ht\tiptext}%
\edef\tdp{\the\dp\tiptext}%
\measureremainder{\whatsleft}\tipshift=0pt%
\ifdim\whatsleft<\twd\setlength\tipshift{\whatsleft-\twd}\fi%
\IfBooleanF{#2}{\tpPdfXform{\tiptext}}%
\raisebox{\heightof{#6}+\tdp}[0pt][0pt]{\makebox[0pt][l]{\hspace{\tipshift}%
\IfBooleanTF{#2}{\usebox{\tiptext}}{%
\tpPdfAnnot{\twd}{\tht}{\tdp}{%
/Subtype/Widget/FT/Btn/T (tip.\thetcnt)%
/AP<</N \tpPdfLastXform>>%
/MK<</TP 1/I \tpPdfLastXform/IF<</S/A/FB true/A [0.0 0.0]>>>>%
/Ff 65536/F 3%
/AA <<%
/U <<%
/S/JavaScript/JS(%
var fd=event.target;%
var mX=this.mouseX;var mY=this.mouseY;%
var drag=function(){%
var nX=this.mouseX;var nY=this.mouseY;%
var dX=nX-mX;var dY=nY-mY;%
var fdr=fd.rect;%
fdr[0]+=dX;fdr[1]+=dY;fdr[2]+=dX;fdr[3]+=dY;%
fd.rect=fdr;mX=nX;mY=nY;%
};%
if(!dragging\thetcnt){%
dragging\thetcnt=true;Int=app.setInterval("drag()",1);%
}%
else{app.clearInterval(Int);dragging\thetcnt=false;}%
this.dirty=false;%
)%
>>%
>>%
}%
\tpAppendToFields{\tpPdfLastAnn}%
}%
}}%
\stepcounter{tcnt}%
}}
\makeatother
\newsavebox\tiptext\newcounter{tcnt}
\newlength{\whatsleft}\newlength{\tipshift}
\newcommand{\measureremainder}[1]{%
\begin{tikzpicture}[overlay,remember picture]
\path let \p0 = (0,0), \p1 = (current page.east) in
[/utils/exec={\pgfmathsetlength#1{\x1-\x0}\global#1=#1}];
\end{tikzpicture}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\parindent=0pt
\begin{document}\Huge
Einstein's \tooltip{formula}{$E=m c^2$} is well known.
Another famous formula is due to \tooltip{Pythagoras}{$a^2+b^2=c^2$}.
\end{document}


How it works:

Two PDF-Annotations (mouse-sensitive regions) are created: (1) A link around the blue link text, which is breakable across line endings. (2) An interactive (/Ff 65536) button (/FT/Btn) widget (/Subtype/Widget) for the tip text.

Visibility of the tip box is controlled via a JavaScript action that is bound to the mouse-enter event of the link. In order to show/hide the tip it is sufficient to repeatedly hover the mouse pointer over the link text.

The tip text may not be directly embedded into the page content; it couldn't be moved around otherwise. Rather, it is typeset into a box (\sbox) and subsequently distilled into a so-called Form-XObject, which is a self-contained PDF entity with graphical and/or textual content. This Form-XObject is bound to the button widget appearance via the /MK entry.

The dragging is implemented as a JavaScript action, which is triggered by the mouse-up event of the tip-text button. The mouse movement is tracked by the function drag() which is repeatedly executed using a JavaScript timer (app.setInterval). The deltas of the mouse position thus determined are continuously added to the coordinates (rect property) of the JavaScript Field object that represents the tip-text button.

• That looks great, AlexG! Could you please add some comment on what each part of your code is doing, so that I (and others) can understand it more easily? Thanks! Apr 16, 2013 at 15:33
• Currently I am a bit short of time. Will do that later. Apr 17, 2013 at 6:33
• @MikaH: ...Done. Plus some code fixes. Apr 19, 2013 at 11:57
• @AlexG Mother of God! img.mu.cdn.li/Ao/xqefEH.jpg Excellent work! Questions: Could it be made so that (in your MWE) "formula" could be replaced by \eqref{}, if you know what I mean? Also, does the end-user require anything other than a PDF viewer? Apr 19, 2013 at 14:52
• For further updates of the \tooltip command, see tex.stackexchange.com/a/111932 May 16, 2013 at 12:05