# How to make a pgfooclass persistent across a beamer presentation?

I would like to define a tikz image element that I could re-use along a beamer presentation. I tried to define this as a pgfooclass, but this seems to be that I can only instantiate objects of a class in the frame where the class has been defined, and similarly, I can only use an instantiated object in the frame where it has been instantiated.

If I try to instantiate in a frame an object of a class defined outside a frame, I get an "Unknown class" error. I can instantiate such an object outside a frame, but I get an "Undefined control sequence" error when I try to use the object inside a frame.

Solved: The problem was due to the ignorenonframetext beamer option. It turns out that pgfooclasses can be defined before the \begin{document}, and be then usable in frames, even with the ignorenonframetext option

Example:

\documentclass[ignorenonframetext]{beamer}
%\documentclass{beamer}

\usepackage{tikz}
\usepgfmodule{oo}

\author{bli}

% defining a class before the document
\pgfooclass{outdocclass}{
\method outdocclass(){}
\method draw(){
\node (outdoc) at (0,0) {outdoc};
}
}

\begin{document}

% defining a class outside a frame
\pgfooclass{outclass}{
\method outclass(){}
\method draw(){
\node (out) at (0,0) {out};
}
}
% instantiating an object of this class outside a frame works
%\pgfoonew \outobject=new outclass()

\begin{frame}{Class outclass is defined outside frames, and outdocclass before the beginning of the document}

Class outclass is instantiated as outobject outside frames

Class outdocclass is instantiated as outdocobject in this frame
% instantiating an object of the outocclass
\pgfoonew \outdocobject=new outdocclass()

\begin{tikzpicture}
\node at (0,1) {object outobject can be used in this picture};
%\outobject.draw()
% if the option ignorenonframetext is used:
%! Undefined control sequence.
%\beamer@doifinframe ... this picture}; \outobject
%                                                  .draw() \end {tikzpicture}...
%l.50 \end{frame}
\node[text width=0.75\textwidth] at (0,-1) {object outdocobject can be used in this picture, even with the ignorenonframetext beamer option};
\outdocobject.draw()
\end{tikzpicture}

\end{frame}

\end{document}

-
Welcome to TeX.sx! Please add a minimal working example (MWE) that illustrates your problem. I've just tried the obvious tests and it worked for me so there may be something particular in your setup that means it isn't working. If you could post some code, that would be very useful in tracking down the problem. –  Loop Space Oct 3 '12 at 19:46
Trying to make a MWE made me find the problem: I was using the beamer option ignorenonframetext, which caused the classes defined out of a frame to be un-recognised in frames. I guess there is no solution to this problem but to redefine the classes in each frame that need them if I want to use this option... Would it be possible to define classes in a .sty file and use them despite the ignorenonframetext option? –  bli Oct 4 '12 at 13:16
@bli Please, add an example of what you're trying to do. –  egreg Oct 4 '12 at 13:22
@bli I had a suspicion that might be the case! The ignorenonframetext option only affects text after the \begin{document}. Is there any reason why you can't declare your classes before the \begin{document}? –  Loop Space Oct 4 '12 at 13:44
I think you can also turn off the ignorenonframetext temporarily by using \mode commands. So if you wrapped the declaration in \mode<all>{...} then that might work. –  Loop Space Oct 4 '12 at 13:47

As suggested by Andrew Stacey, two techniques can be used to make pgfooclasses available throughout a beamer presentation, even when the ignorenonframetext beamer option is used.

One consists in defining the class before the \begin{document}, because the ignorenonframetext is not yet active at this stage.

The other consists in defining the class in a \mode<all>{...} mode, whereby the option is temporarily ignored.

Here is an example where the two techniques are used:

\documentclass[ignorenonframetext]{beamer}

\usepackage{tikz}
\usepgfmodule{oo}

\author{bli, with suggestions from Andrew Stacey}

% defining a class before the document begins
\pgfooclass{outdocclass}{
\method outdocclass(){}
\method draw(){
\node (outdoc) at (-1,0) {outdoc};
}
}

\begin{document}

% having the outside frame class definition taken into account in presentation mode,
% despite the ignorenonframetext option
\mode<all>{
% defining a class outside a frame
\pgfooclass{outframeclass}{
\method outframeclass(){}
\method draw(){
\node (outframe) at (1,0) {outframe};
}
}

% instantiating an object of this class outside a frame
\pgfoonew \outframeobject=new outframeclass()
}

\begin{frame}{Class outframeclass is defined outside frames, and outdocclass before the beginning of the document}

% instantiating an object of the outdocclass
outdocclass is instantiated as outdocobject in this frame.\\
This is possible even with the \texttt{ignorenonframetext} option
because this option takes effect only after the document has begun.
\pgfoonew \outdocobject=new outdocclass()

\begin{tikzpicture}
\node[text width=0.75\textwidth] at (0,1) {object outobject can be used in this picture,
because it was instantiated in \texttt{mode<all>}};
\outframeobject.draw()
\node[text width=0.75\textwidth] at (0,-1) {object outdocobject can be used in this picture};
\outdocobject.draw()
\end{tikzpicture}

\end{frame}

\end{document}


Note that the instantiating could be done at other places. What matters is that the class definition is "accessible" from where the instantiating takes place, and that the resulting object is "accessible" from where it is used.

-