如何使用 pgfkeys 检测填充颜色选项

如何使用 pgfkeys 检测填充颜色选项

我有以下代码部分:

\pgfkeys{
  /tikz/.cd,
  color izquierda/.initial=\tikz@fillcolor,
  color derecha/.initial=\tikz@fillcolor,
}

它可以工作,但如果我没有激活这两个选项,如果未选择选项“fill=any color”,则会收到错误。请问有人能帮我吗?我还需要检测是否选择了填充选项。提前致谢!

这里是 MWE:

\documentclass[]{article}

\usepackage{tikz,makeshape}

\def\gap{0mm}

\makeatletter

% Dimensiones medidas en Autocad para las válvulas con anchura = 3mm en un
% círculo de 2mm de radio.

\def\radio@llave{2mm}
\def\x@llave{1.5mm}
\def\y@llave{1.32mm}

\pgfkeys{
    % Requiere que fill=color esté activado en caso de no estar izq. y dcha.
    /tikz/.cd,
    color izquierda/.initial=\tikz@fillcolor,
    color derecha/.initial=\tikz@fillcolor
}

%% Anchor path:

\def\llaveanchor{ % Obtiene la caja de texto correcta:

    \pgf@xa=\ctbnex
    \pgf@ya=\ctbney

    % Crea el margen para la forma:
    \advance\pgf@xa by \gap
    \advance\pgf@ya by \gap
    % Corrige minheight y minwidth, y outerxsep o outerysep:
    \mincorrect{\pgf@xa}{\pgfshapeminwidth}
    \advance\pgf@xa\pgfshapeouterxsep
    \mincorrect{\pgf@ya}{\pgfshapeminheight}
    \advance\pgf@ya\pgfshapeouterysep
    % Dibuja el anchor con \pgfusepath{stroke}:
    \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
    \pgfpathlineto{\pgfpoint{\pgf@xa}{-\pgf@ya}}
    \pgfpathlineto{\pgfpoint{-\pgf@xa}{-\pgf@ya}}
    \pgfpathlineto{\pgfpoint{-\pgf@xa}{\pgf@ya}}
    \pgfpathclose 
    % lo siguiente solo para comprobar
    %\pgfusepath{stroke}

}

%% Background path:

\def\llaveborder{ % Obtiene la caja de texto correcta:

    \pgf@xa=\ctbnex
    \pgf@ya=\ctbney

    % Crea el margen para la forma:
    \advance\pgf@xa by \gap
    \advance\pgf@ya by \gap
    % Corrige minheight y minwidth, y outerxsep o outerysep:
    \mincorrect{\pgf@xa}{\pgfshapeminwidth}
    \advance\pgf@xa\pgfshapeouterxsep
    \mincorrect{\pgf@ya}{\pgfshapeminheight}
    \advance\pgf@ya\pgfshapeouterysep
    %
    % Dibuja el círculo:
    %
    \pgfcircle{\pgfpointorigin}{\radio@llave}
    % con la opción clip evito los picos de la válvula saliendo el círculo
    \pgfusepath{fill,stroke,clip}
    %
    % Triángulo izquierdo:
    %
    \pgfsetfillcolor{\pgfkeysvalueof{/tikz/color izquierda}}
    %
    \pgfpathmoveto{\pgfpointorigin}
    \pgfpathlineto{\pgfpoint{-\x@llave}{ \y@llave}}
    \pgfpathlineto{\pgfpoint{-\x@llave}{-\y@llave}}
    \pgfpathclose
    \pgfusepath{fill,stroke}
    %
    % Triángulo derecho:
    %
    \pgfsetfillcolor{\pgfkeysvalueof{/tikz/color derecha}}
    %
    \pgfpathmoveto{\pgfpointorigin}
    \pgfpathlineto{\pgfpoint{ \x@llave}{ \y@llave}}
    \pgfpathlineto{\pgfpoint{ \x@llave}{-\y@llave}}
    \pgfpathclose
    \pgfusepath{fill,stroke}
    %
    % Línea vertical:
    %
    \pgfpathmoveto{\pgfpoint{0}{ \radio@llave}}
    \pgfpathlineto{\pgfpoint{0}{-\radio@llave}}
    \pgfusepath{stroke}

}

%% Declaración de la forma:

\pgfdeclareshape{llave toma en carga}{

    \setpaths{\llaveanchor}{\llaveborder}

    \savedanchor{\centerpoint}{
        \pgf@x = \ctbnex
        \pgf@y = \ctbney
        \advance\pgf@x by \gap
        \advance\pgf@y by \gap
        \mincorrect{\pgf@x}{\pgfshapeminwidth}
        \mincorrect{\pgf@y}{\pgfshapeminheight}
        \advance\pgf@x\pgfshapeouterxsep
        \advance\pgf@y\pgfshapeouterysep
    }

    % Anchors:
    \anchor{c}{\centerpoint \pgf@x=0pt \pgf@y=0pt}
    %
    \anchor{u}{\centerpoint \pgf@x=0pt \pgf@y= \radio@llave}
    \anchor{d}{\centerpoint \pgf@x=0pt \pgf@y=-\radio@llave}
    \anchor{r}{\centerpoint \pgf@x= \radio@llave \pgf@y=0pt}
    \anchor{l}{\centerpoint \pgf@x=-\radio@llave \pgf@y=0pt}
    %
    \anchor{ur}{\centerpoint \pgf@x= \x@llave \pgf@y= \y@llave}
    \anchor{dr}{\centerpoint \pgf@x= \x@llave \pgf@y=-\y@llave}
    \anchor{ul}{\centerpoint \pgf@x=-\x@llave \pgf@y= \y@llave}
    \anchor{dl}{\centerpoint \pgf@x=-\x@llave \pgf@y=-\y@llave}

}

\makeatother

\tikzset{
  st valvula/.style={
    draw,minimum width=3mm,minimum height=2.85mm,line width=0.1mm,inner sep=0em,scale=2
  }
}

\pagestyle{empty}
\begin{document}

When 'fill' and 'color izquierda'/'color derecha' are commented, an error is obtained. A way to detect if 'fill' is uncommented is necesary.
Moreover, there would be feasible not to fill anything.

\begin{center}
\begin{tikzpicture}[x=1mm,y=1mm]
    \node[%
    llave toma en carga,st valvula,scale=2,
    fill=gray!15,
    color izquierda=cyan,
    color derecha=red!50
  ] (v2) at (0,0) {};
\end{tikzpicture}
\end{center}

\end{document}

其收益为:

在此处输入图片描述

答案1

抱歉,我没说话,但我真的很忙。这个方法似乎有效,我注释掉了\typeouts 来说明如何调试。

\documentclass[]{article}

\usepackage{tikz,makeshape}

\def\gap{0mm}

\makeatletter

% Dimensiones medidas en Autocad para las válvulas con anchura = 3mm en un
% círculo de 2mm de radio.

\def\radio@llave{2mm}
\def\x@llave{1.5mm}
\def\y@llave{1.32mm}

\pgfkeys{
    % Requiere que fill=color esté activado en caso de no estar izq. y dcha.
    /tikz/.cd,
    color izquierda/.initial=\pgfutil@empty,
    %color izquierda/.default=\pgfutil@empty,
    color derecha/.initial=\pgfutil@empty%
}

%% Anchor path:

\def\llaveanchor{ % Obtiene la caja de texto correcta:

    \pgf@xa=\ctbnex
    \pgf@ya=\ctbney

    % Crea el margen para la forma:
    \advance\pgf@xa by \gap
    \advance\pgf@ya by \gap
    % Corrige minheight y minwidth, y outerxsep o outerysep:
    \mincorrect{\pgf@xa}{\pgfshapeminwidth}
    \advance\pgf@xa\pgfshapeouterxsep
    \mincorrect{\pgf@ya}{\pgfshapeminheight}
    \advance\pgf@ya\pgfshapeouterysep
    % Dibuja el anchor con \pgfusepath{stroke}:
    \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
    \pgfpathlineto{\pgfpoint{\pgf@xa}{-\pgf@ya}}
    \pgfpathlineto{\pgfpoint{-\pgf@xa}{-\pgf@ya}}
    \pgfpathlineto{\pgfpoint{-\pgf@xa}{\pgf@ya}}
    \pgfpathclose 
    % lo siguiente solo para comprobar
    %\pgfusepath{stroke}

}

%% Background path:

\def\llaveborder{ % Obtiene la caja de texto correcta:

    \pgf@xa=\ctbnex
    \pgf@ya=\ctbney

    % Crea el margen para la forma:
    \advance\pgf@xa by \gap
    \advance\pgf@ya by \gap
    % Corrige minheight y minwidth, y outerxsep o outerysep:
    \mincorrect{\pgf@xa}{\pgfshapeminwidth}
    \advance\pgf@xa\pgfshapeouterxsep
    \mincorrect{\pgf@ya}{\pgfshapeminheight}
    \advance\pgf@ya\pgfshapeouterysep
    %
    % Dibuja el círculo:
    %
    \pgfcircle{\pgfpointorigin}{\radio@llave}
    % con la opción clip evito los picos de la válvula saliendo el círculo
    \pgfusepath{fill,stroke,clip}
    %
    % Triángulo izquierdo:
    %
    %\typeout{izquierda\pgfkeysvalueof{/tikz/color izquierda}}
    \edef\pgfutil@tmpa{\pgfkeysvalueof{/tikz/color izquierda}}
    \ifx\pgfutil@tmpa\pgfutil@empty
         %\typeout{izquierda\space empty}
    \else
        \pgfsetfillcolor{\pgfkeysvalueof{/tikz/color izquierda}}
    \fi 
    %
    \pgfpathmoveto{\pgfpointorigin}
    \pgfpathlineto{\pgfpoint{-\x@llave}{ \y@llave}}
    \pgfpathlineto{\pgfpoint{-\x@llave}{-\y@llave}}
    \pgfpathclose
    \pgfusepath{fill,stroke}
    %
    % Triángulo derecho:
    %
    %\typeout{derecha\pgfkeysvalueof{/tikz/color derecha}}
    \edef\pgfutil@tmpa{\pgfkeysvalueof{/tikz/color derecha}}
    \ifx\pgfutil@tmpa\pgfutil@empty
        %\typeout{derecha\space empty}
    \else
    \pgfsetfillcolor{\pgfkeysvalueof{/tikz/color derecha}}
    \fi
    %
    \pgfpathmoveto{\pgfpointorigin}
    \pgfpathlineto{\pgfpoint{ \x@llave}{ \y@llave}}
    \pgfpathlineto{\pgfpoint{ \x@llave}{-\y@llave}}
    \pgfpathclose
    \pgfusepath{fill,stroke}
    %
    % Línea vertical:
    %
    \pgfpathmoveto{\pgfpoint{0}{ \radio@llave}}
    \pgfpathlineto{\pgfpoint{0}{-\radio@llave}}
    \pgfusepath{stroke}

}

%% Declaración de la forma:

\pgfdeclareshape{llave toma en carga}{

    \setpaths{\llaveanchor}{\llaveborder}

    \savedanchor{\centerpoint}{
        \pgf@x = \ctbnex
        \pgf@y = \ctbney
        \advance\pgf@x by \gap
        \advance\pgf@y by \gap
        \mincorrect{\pgf@x}{\pgfshapeminwidth}
        \mincorrect{\pgf@y}{\pgfshapeminheight}
        \advance\pgf@x\pgfshapeouterxsep
        \advance\pgf@y\pgfshapeouterysep
    }

    % Anchors:
    \anchor{c}{\centerpoint \pgf@x=0pt \pgf@y=0pt}
    %
    \anchor{u}{\centerpoint \pgf@x=0pt \pgf@y= \radio@llave}
    \anchor{d}{\centerpoint \pgf@x=0pt \pgf@y=-\radio@llave}
    \anchor{r}{\centerpoint \pgf@x= \radio@llave \pgf@y=0pt}
    \anchor{l}{\centerpoint \pgf@x=-\radio@llave \pgf@y=0pt}
    %
    \anchor{ur}{\centerpoint \pgf@x= \x@llave \pgf@y= \y@llave}
    \anchor{dr}{\centerpoint \pgf@x= \x@llave \pgf@y=-\y@llave}
    \anchor{ul}{\centerpoint \pgf@x=-\x@llave \pgf@y= \y@llave}
    \anchor{dl}{\centerpoint \pgf@x=-\x@llave \pgf@y=-\y@llave}

}

\makeatother

\tikzset{
  st valvula/.style={
    draw,minimum width=3mm,minimum height=2.85mm,line width=0.1mm,inner sep=0em,scale=2
  }
}

\pagestyle{empty}
\begin{document}

When 'fill' and 'color izquierda'/'color derecha' are commented, an error is obtained. A way to detect if 'fill' is uncommented is necesary.
Moreover, there would be feasible not to fill anything.

\begin{center}
\begin{tikzpicture}[x=1mm,y=1mm]
    \node[%
    llave toma en carga,st valvula,scale=2,
    fill=gray!15,
    %color izquierda=cyan,
    color derecha=red!50
  ] (v2) at (0,0) {};
\end{tikzpicture}
\end{center}

\end{document}

相关内容