我正在研究一个新的 beamer 主题,我想知道是否有可能检索最后发货的高度beamercolorbox
。为了设置一个合理的最小(虽然看起来很可怕)工作示例,让我们专注于模板frametitle
,让我们假设(就像在许多主题中一样)框架标题基本上放在了 中beamercolorbox
。
\documentclass{beamer}
\usetheme{Madrid}
\makeatletter
\defbeamertemplate*{frametitle}{myFrametitle}[1][left]
{
\begin{beamercolorbox}[sep=0.3cm,wd=\textwidth]{frametitle}
\usebeamerfont{frametitle}%
\strut\insertframetitle\strut\par%
{%
\ifx\insertframesubtitle\@empty%
\else%
{\usebeamerfont{framesubtitle}\usebeamercolor[fg]{framesubtitle}\insertframesubtitle\strut\par}%
\fi
}%
\end{beamercolorbox}%
%-----
% Here I would like to have a length with the height of the
% above beamercolorbox, to be used to adapt dynamically stuff
%-----
}
\makeatother
\setbeamertemplate{frametitle}[myFrametitle]
\begin{document}
\begin{frame}{Frame title}
A frame
\end{frame}
\begin{frame}{Frame title}{with subtitle}
Another frame
\end{frame}
\end{document}
有没有一种优雅的方法来检索最后一个环境中的盒子的高度beamercolorbox
?
更多信息
阅读
beamerbasecolor.sty
文件时,我想我可以重新定义beamercolorbox
环境,添加如下行\global\setlength{\@lastbeamercolorboxheight}{\ht\beamer@tempbox}%
在每个 之前
\box\beamer@tempbox%
,其中将\@lastbeamercolorboxheight
是我的主题的内部长度。但是,我不喜欢为了最小的附加组件而复制大量 beamer 代码的想法,而且,它看起来也不太好优雅的也不是可行的方法(请参阅下文了解此方法的具体示例)。我知道我可能会使用
ht
和dp
键来beamercolorbox
固定框的高度,但这对我来说不是一个有效的方法。更像是,用户将她/他想要的任何内容放入框架标题/副标题中,然后我相应地动态采取行动。我很高兴收到任何一般性的提示,并且可能欢迎稍有不同的方法。
如果优雅的解决方案是根本不使用
beamercolorbox
,那么我会从更普遍的角度考虑替代方案。
重新定义beamercolorbox
环境
虽然这不是一个优雅的检索框高度的方法,可以访问所需的长度。但是,可能存在许多缺点,但此处的代码可能会帮助读者提出更好的方法。
\documentclass{beamer}
\usetheme{Madrid}
\makeatletter
\newlength{\@lastbeamercolorboxheight}
\renewenvironment{beamercolorbox}[2][]{% taken from beamerbasecolor.sty
\begingroup%
\def\beamer@colbox@coladd{0pt}%
\def\beamer@vmode{\leavevmode}%
\setkeys{beamercolbox}{%
wd=\textwidth,ht={},dp={},%
leftskip=0pt,rightskip=0pt plus1fil,%
sep=0pt,colsep=0pt,colsep*=0pt,%
shadow=false,rounded=false,ignorebg=false}%
\setkeys{beamercolbox}{#1}%
\ifbeamercolorempty[bg]{#2}{\@tempswafalse}{\@tempswatrue}%
\ifbeamer@colbox@ignorebg\@tempswafalse\fi%
\def\beamer@colbox@color{#2}%
\hsize=\beamer@colbox@wd%
\setbox\beamer@tempbox=\hbox\bgroup\vbox\bgroup%
\leftskip=\beamer@colbox@ls%
\advance\leftskip by\beamer@colbox@sep%
\rightskip=\beamer@colbox@rs%
\advance\rightskip by\beamer@colbox@sep%
\ifbeamer@colbox@ignorebg%
\colorlet{beamer@temp@color}{bg}%
\usebeamercolor[fg]{#2}%
\colorlet{bg}{beamer@temp@color}%
\else%
\usebeamercolor[fg]{#2}%
\fi%
\if@tempswa%
\advance\leftskip by\beamer@colbox@colsep%
\advance\rightskip by\beamer@colbox@colsep%
\ifdim\beamer@colbox@colsep=0pt\else\vskip\beamer@colbox@colsep\fi%
\ifdim\beamer@colbox@colseps=0pt\else\vskip\beamer@colbox@colseps\fi%
\fi%
\ifdim\beamer@colbox@sep=0pt\else\vskip\beamer@colbox@sep\fi%
\beamer@vmode\ignorespaces}{%
\ifdim\beamer@colbox@sep=0pt\else\vskip\beamer@colbox@sep\fi%
\if@tempswa\ifdim\beamer@colbox@colsep=0pt\else\vskip\beamer@colbox@colsep\fi\fi%
\if@tempswa\ifdim\beamer@colbox@colseps=0pt\else\vskip\beamer@colbox@colseps\fi\fi%
\egroup\egroup%
\wd\beamer@tempbox=\hsize%
\@tempdima=\wd\beamer@tempbox%
\ifx\beamer@colbox@ht\@empty%
\else%
\ht\beamer@tempbox=\beamer@colbox@ht%
\fi%
\ifx\beamer@colbox@dp\@empty%
\else%
\dp\beamer@tempbox=\beamer@colbox@dp%
\fi%
\ifbeamer@colbox@rounded%
\if@tempswa%
\begin{beamerboxesrounded}[%
shadow=\beamer@colbox@shadow,%
lower=\beamer@colbox@color,%
upper=normal text,%
width=\beamer@colbox@wd]{}%
\global\setlength{\@lastbeamercolorboxheight}{\ht\beamer@tempbox}% <--- ADDED
\box\beamer@tempbox%
\end{beamerboxesrounded}%
\else%
\ifdim\@tempdima>\textwidth%
\setbox\beamer@tempbox=\hbox to\textwidth{\hss\box\beamer@tempbox\hss}%
\fi%
\global\setlength{\@lastbeamercolorboxheight}{\ht\beamer@tempbox}% <--- ADDED
\box\beamer@tempbox%
\fi%
\else%
\if@tempswa\setbox\beamer@tempbox=\hbox{\vbox{%
\usebeamercolor{\beamer@colbox@color}%
\advance\hsize by \beamer@colbox@colseps\relax%
\advance\hsize by \beamer@colbox@colseps\relax%
\hskip-\beamer@colbox@colseps%
\fboxsep=0pt\colorbox{bg}{%
\hskip\beamer@colbox@colseps%
\hbox{\box\beamer@tempbox}%
\hskip\beamer@colbox@colseps%
}%
\hskip-\beamer@colbox@colseps%
}}\fi%
\ifdim\@tempdima>\textwidth%
\setbox\beamer@tempbox=\hbox to\textwidth{\hskip0pt minus\beamer@leftmargin\relax\box\beamer@tempbox\hskip0pt minus\beamer@rightmargin\relax}%
\fi%
\global\setlength{\@lastbeamercolorboxheight}{\ht\beamer@tempbox}% <--- ADDED
\box\beamer@tempbox%
\fi%
\endgroup%
}
\defbeamertemplate*{frametitle}{myFrametitle}
{
\begin{beamercolorbox}[sep=0.3cm,wd=\textwidth]{frametitle}
\usebeamerfont{frametitle}%
\strut\insertframetitle\strut\par%
{%
\ifx\insertframesubtitle\@empty%
\else%
{\usebeamerfont{framesubtitle}\usebeamercolor[fg]{framesubtitle}\insertframesubtitle\strut\par}%
\fi
}%
\end{beamercolorbox}%
%-----
% Here the length \@lastbeamercolorboxheight is set to the height of the box above
\textcolor{black}{\the\@lastbeamercolorboxheight}
}
\makeatother
\setbeamertemplate{frametitle}[myFrametitle]
\begin{document}
\begin{frame}{Frame title}
A frame
\end{frame}
\begin{frame}{Frame title}{with subtitle}
Another frame
\end{frame}
\end{document}
结果如下。
答案1
beamercolorbox
您可以通过修补而不是重新定义来简化代码:
\documentclass{beamer}
\usetheme{Madrid}
\makeatletter
\newlength{\@lastbeamercolorboxheight}
\patchcmd{\endbeamercolorbox}{
\box\beamer@tempbox%
}{%
\global\setlength{\@lastbeamercolorboxheight}{\ht\beamer@tempbox}%
\box\beamer@tempbox%
}{}{}
\patchcmd{\endbeamercolorbox}{
\box\beamer@tempbox%
}{%
\global\setlength{\@lastbeamercolorboxheight}{\ht\beamer@tempbox}%
\box\beamer@tempbox%
}{}{}
\patchcmd{\endbeamercolorbox}{
\box\beamer@tempbox%
}{%
\global\setlength{\@lastbeamercolorboxheight}{\ht\beamer@tempbox}%
\box\beamer@tempbox%
}{}{}
\addtobeamertemplate{frametitle}{}{\textcolor{black}{\the\@lastbeamercolorboxheight}}
\makeatother
\begin{document}
\begin{frame}{Frame title}
A frame
\end{frame}
\begin{frame}{Frame title}{with subtitle}
Another frame
\end{frame}
\end{document}