如何在 beamercolorbox 环境中检索框的高度?

如何在 beamercolorbox 环境中检索框的高度?

我正在研究一个新的 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 代码的想法,而且,它看起来也不太好优雅的也不是可行的方法(请参阅下文了解此方法的具体示例)。

  • 我知道我可能会使用htdp键来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}

相关内容