% -----------------------------------------------------------
% This is TikZ Osci package
%
% It allows you to produce oscilloscope "screen shots".
%
% It is based on TikZ and pgfplots and is a replacement can-
% didate to the pstricks pst-osci package which is not main-
% tained anymore.
%
% Author: Thibault Giauffret
% Date: 2023/10/24
% Version: 0.4.0
% Licence : Released under the LaTeX Project Public License v1.3c or later, see http://www.latex-project.org/lppl.txtf
% Not an expert... Just doing it for fun.
% -----------------------------------------------------------

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{tikz-osci}[2023/10/24 0.4.0 Tikz Osci package]

% Required packages
\RequirePackage[dvipsnames]{xcolor}
\RequirePackage{pgfkeys}
\RequirePackage{pgfplots}
\RequirePackage{tikz}
\usetikzlibrary{arrows,shapes,positioning,decorations.markings,decorations.pathmorphing,
 decorations.pathreplacing,calc,patterns,shapes.geometric}

% Raised text
\newcommand*{\raisedtext}[1]{%
 \begingroup
   \leavevmode
   \rlap{\kern-.2pt\raise.2pt\hbox{\color{white}#1}}%
   \rlap{\kern.2pt\raise-.2pt\hbox{\color{black!30}#1}}%
   \hbox{#1}%
 \endgroup
}

% The main command
\newcommand\osci[1][]{

 % Init the keys and get the values and add the user's values
 \pgfkeys{
   /osci/.cd,
   scale/.store in=\scale,
   scale=1,
   rounded corners/.store in=\roundedCorners,
   rounded corners=10,
   second channel/.store in=\secondChannel,
   second channel=0,
   screen offset one/.store in=\screenOffsetOne,
   screen offset one=0,
   screen offset two/.store in=\screenOffsetTwo,
   screen offset two=-0,
   time div/.store in=\timeDiv,
   time div=20,
   voltage div one/.store in=\voltageDivOne,
   voltage div one=1,
   voltage div two/.store in=\voltageDivTwo,
   voltage div two=1,
   sample rate/.store in=\sampleRate,
   sample rate=200,
   xy mode/.store in=\xyMode,
   xy mode=0,
   math mode/.store in=\mathMode,
   math mode=0,
   math mode hide source/.store in=\mathModeHideSource,
   math mode hide source=0,
   func one/.store in=\funcOne,
   func one=2*sin(2*180/0.020*x),
   func two/.store in=\funcTwo,
   func two=0.6*sin(2*180/0.020*x)+0.2*sin(2*180/0.040*x),
   indicators/.store in=\indicators,
   indicators=1,
   vertical cursor one/.store in=\verticalCursorOne,
   vertical cursor one=false,
   vertical cursor two/.store in=\verticalCursorTwo,
   vertical cursor two=false,
   horizontal cursor one/.store in=\horizontalCursorOne,
   horizontal cursor one=false,
   horizontal cursor two/.store in=\horizontalCursorTwo,
   horizontal cursor two=false,
   cursor precision/.store in=\cursorPrecision,
   cursor precision=1,
   color one/.store in=\colorOne,
   color one=D62626,
   color text one/.store in=\colorTextOne,
   color text one=FFFFFF,
   color two/.store in=\colorTwo,
   color two=1053AF,
   color text two/.store in=\colorTextTwo,
   color text two=FFFFFF,
   color three/.store in=\colorThree,
   color three=2E8B73,
   color text three/.store in=\colorTextThree,
   color text three=FFFFFF,
   graph back color/.store in=\graphBackColor,
   graph back color=FFFFFF,
   info back color/.store in=\infoBackColor,
   info back color=D6D6D6,
   info text color/.store in=\infoTextColor,
   info text color=000000,
   main axis color/.store in=\mainAxisColor,
   main axis color=000000,
   grid color/.store in=\gridColor,
   grid color=AAAAAA,
   horizontal cursor color/.store in=\horizontalCursorColor,
   horizontal cursor color=FFA500,
   vertical cursor color/.store in=\verticalCursorColor,
   vertical cursor color=800080,
   smooth one/.store in=\smoothOne,
   smooth one=0,
   smooth two/.store in=\smoothTwo,
   smooth two=0,
   smooth three/.store in=\smoothThree,
   smooth three=0,
   #1
 }


 % Set the scale of the picture
 \scalebox{\scale}{
   % Begin the picture
   \begin{tikzpicture}

     % Set the colors
     \definecolor{firstcolor}{HTML}{\colorOne}
     \definecolor{secondcolor}{HTML}{\colorTwo}
     \definecolor{thirdcolor}{HTML}{\colorThree}
     \definecolor{graphbackcolor}{HTML}{\graphBackColor}
     \definecolor{infoBackColor}{HTML}{\infoBackColor}
     \definecolor{infoTextColor}{HTML}{\infoTextColor}
     \definecolor{mainAxisColor}{HTML}{\mainAxisColor}
     \definecolor{gridColor}{HTML}{\gridColor}
     \definecolor{colorTextOne}{HTML}{\colorTextOne}
     \definecolor{colorTextTwo}{HTML}{\colorTextTwo}
     \definecolor{colorTextThree}{HTML}{\colorTextThree}
     \definecolor{verticalCursorColor}{HTML}{\verticalCursorColor}
     \definecolor{horizontalCursorColor}{HTML}{\horizontalCursorColor}

     % Draw the info box
     \draw[black,thick, fill= infoBackColor]
     (0,0) --
     ++(10,0) {[rounded corners=\roundedCorners] --
       ++(0,-1.5) --
       ++(-10,0)} --
     cycle
       {};

     % Add time/div label
     \draw (5,-0.15) node[anchor=north, color= infoTextColor] {\timeDiv\ ms/div};

     % Test if smoothOne is enabled
     \ifnum\smoothOne=1
       % set \smoothOne to smooth
       \def\smoothOne{smooth}
     \else
       % set \smoothOne to empty
       \def\smoothOne{}
     \fi

     % Test if smoothTwo is enabled
     \ifnum\smoothTwo=1
       % set \smoothTwo to smooth
       \def\smoothTwo{smooth}
     \else
       % set \smoothTwo to empty
       \def\smoothTwo{}
     \fi

     % Test if smoothThree is enabled
     \ifnum\smoothThree=1
       % set \smoothThree to smooth
       \def\smoothThree{smooth}
     \else
       % set \smoothThree to empty
       \def\smoothThree{}
     \fi

     % Add XY mode indicator
     % Lissajou mode
     \ifnum\xyMode=1

       \draw[thirdcolor,fill=thirdcolor] (4,-0.78) rectangle (6,-1.28);
       \draw (5,-0.75) node[anchor=north, color=colorTextThree] {XY mode};

     \else

       % Add mode
       \ifnum\mathMode=1

         \draw[thirdcolor,fill=thirdcolor] (4,-0.78) rectangle (6,-1.28);
         \draw (5,-0.75) node[anchor=north, color=colorTextThree] {Add};

       \else

         % Substract mode
         \ifnum\mathMode=2

           \draw[thirdcolor,fill=thirdcolor] (4,-0.78) rectangle (6,-1.28);
           \draw (5,-0.75) node[anchor=north, color=colorTextThree] {Substract};

         \else

           % Multiply mode
           \ifnum\mathMode=3

             \draw[thirdcolor,fill=thirdcolor] (4,-0.78) rectangle (6,-1.28);
             \draw (5,-0.75) node[anchor=north, color=colorTextThree] {Multiply};

           \else

             % Divide mode
             \ifnum\mathMode=4

               \draw[thirdcolor,fill=thirdcolor] (4,-0.78) rectangle (6,-1.28);
               \draw (5,-0.75) node[anchor=north, color=colorTextThree] {Divide};

             \fi
           \fi
         \fi
       \fi
     \fi

     % Add voltage/div label for the first channel
     \draw[firstcolor,fill=firstcolor] (0.5,-0.15) rectangle (1.5,-0.6);
     \draw (1,-0.1) node[anchor=north, color=colorTextOne] {CH1};
     \draw (1,-0.75) node[anchor=north, color= infoTextColor] {\voltageDivOne\ V/div};

     % Add voltage/div label for the second channel
     \ifnum\secondChannel=1
       \draw[secondcolor,fill=secondcolor] (8.5,-0.15) rectangle (9.5,-0.6);
       \draw (9,-0.1) node[anchor=north, color=colorTextTwo]{CH2};
       \draw (9,-0.75) node[anchor=north, color= infoTextColor] {\voltageDivTwo\ V/div};
     \fi

     % Draw the oscilloscope screen border
     \draw[black,thick, fill= graphbackcolor]
     (0,0) --
     ++(10,0) {[rounded corners=\roundedCorners] --
       ++(0,8) --
       ++(-10,0)} --
     cycle
       {};

     % Draw the oscilloscope screen graduations
     \begin{scope}

       % Remove the border
       \clip (0.05,0.05) rectangle (9.95,7.95);

       \begin{axis}[xmin=-5*(\timeDiv/1000), xmax=5*(\timeDiv/1000), ymin=-4, ymax=4, xtick distance = \timeDiv/1000,
           axis x line=middle, axis y line=middle,
           axis line style={-},
           color=mainAxisColor,
           % Draw major grid
           grid=both,
           xticklabels={,,},
           yticklabels={,,},
           % Add sub ticks for the x axis
           minor tick num=4,
           % Remove minor grid
           minor grid style={line width=0pt, draw=white, draw opacity=0},
           major grid style={thick,dashed,draw=gridColor},
           every major tick/.append style={very thick, major tick length=6pt, color=mainAxisColor},
           every minor tick/.append style={thick, minor tick length=4pt, color=mainAxisColor},
         ]

         % Change plot width
         \pgfplotsset{width=11.58cm, height=9.58cm}
         % Change tick label style
         \pgfplotsset{ every non boxed x axis/.append style={x axis line style=-},
           every non boxed y axis/.append style={y axis line style=-}}

         % Lissajous mode
         \ifnum\xyMode=1
           \addplot
           [domain=0:360,variable=\x,
             samples=200,very thick,color=thirdcolor, \smoothThree]
           ({(\funcOne)/\voltageDivOne},{(\funcTwo)/\voltageDivTwo});
           \draw[thirdcolor,fill=thirdcolor] (4,-0.78) rectangle (6,-1.28);
           \draw (5,-0.75) node[anchor=north, color=white] {XY mode};

         \else

           % Show source signals
           \ifnum\mathModeHideSource=0
             % Draw each channel separately
             % First channel plot
             \addplot[color=firstcolor,very thick,domain=-5*(\timeDiv/1000):5*(\timeDiv/1000),samples=\sampleRate,\smoothOne]{(\funcOne)/\voltageDivOne+\screenOffsetOne};

             % If the second channel is enabled, draw it
             \ifnum\secondChannel=1
               % Draw the second channel
               \addplot[color=secondcolor,very thick,domain=-5*(\timeDiv/1000):5*(\timeDiv/1000), samples=\sampleRate,\smoothTwo]{(\funcTwo)/\voltageDivTwo+\screenOffsetTwo};

             \fi
           \fi

           % Add mode
           \ifnum\mathMode=1
             \addplot[color=thirdcolor,very thick,domain=-5*(\timeDiv/1000):5*(\timeDiv/1000),
               smooth, samples=\sampleRate, \smoothThree]{(\funcOne)/\voltageDivOne + (\funcTwo)/\voltageDivTwo};

           \else

             % Substract mode
             \ifnum\mathMode=2
               \addplot[color=thirdcolor,very thick,domain=-5*(\timeDiv/1000):5*(\timeDiv/1000), samples=\sampleRate, \smoothThree]{(\funcOne)/\voltageDivOne - (\funcTwo)/\voltageDivTwo};
               \draw[thirdcolor,fill=thirdcolor] (4,-0.78) rectangle (6,-1.28);
               \draw (5,-0.75) node[anchor=north, color=white] {Substract};

             \else

               % Multiply mode
               \ifnum\mathMode=3
                 \addplot[color=thirdcolor,very thick,domain=-5*(\timeDiv/1000):5*(\timeDiv/1000) ,samples=\sampleRate, \smoothThree]{(\funcOne)/\voltageDivOne * (\funcTwo)/\voltageDivTwo};
                 \draw[thirdcolor,fill=thirdcolor] (4,-0.78) rectangle (6,-1.28);
                 \draw (5,-0.75) node[anchor=north, color=white] {Multiply};

               \else

                 % Divide mode
                 \ifnum\mathMode=4
                   \addplot[color=thirdcolor,very thick,domain=-5*(\timeDiv/1000):5*(\timeDiv/1000), samples=\sampleRate, \smoothThree]{(\funcOne)/\voltageDivOne / (\funcTwo)/\voltageDivTwo};
                   \draw[thirdcolor,fill=thirdcolor] (4,-0.78) rectangle (6,-1.28);
                   \draw (5,-0.75) node[anchor=north, color=white] {Divide};
                 \fi
               \fi
             \fi
           \fi
         \fi

       \end{axis}

       \ifnum\xyMode=1
       \else
         % Show the channel indicators
         \ifnum\indicators=1
           % Draw the first channel's screen marker
           \draw[firstcolor,fill=firstcolor] (0.4, \screenOffsetOne+4) -- (0, \screenOffsetOne+4+0.3) -- (0, \screenOffsetOne+4-0.3) -- cycle;
           \draw (-0.04, \screenOffsetOne+4) node[anchor=west, color=colorTextOne,font=\fontsize{8}{10}\selectfont] {1};


           % Draw the second channel's screen marker
           \ifnum\secondChannel=1
             \draw[secondcolor,fill=secondcolor] (0.4, \screenOffsetTwo+4) -- (0, \screenOffsetTwo+4+0.3) -- (0, \screenOffsetTwo+4-0.3) -- cycle;
             \draw (-0.04, \screenOffsetTwo+4) node[anchor=west, color=colorTextTwo,font=\fontsize{8}{10}\selectfont] {2};
           \fi
         \fi


         % Draw the vertical cursors

         % Define the false value
         \def\false{false}

         % Set the value of \verticalCursorOne
         \pgfmathsetmacro{\verticalCursorOneValue}{\verticalCursorOne*\timeDiv}


         % If the first vertical cursor is enabled
         \ifx\verticalCursorOne\false
         \else
           % Draw the first vertical cursor with \verticalCursorOne value
           \draw[verticalCursorColor,very thick,dashed] (\verticalCursorOne+5,0) -- (\verticalCursorOne+5,8);
           \draw[verticalCursorColor,very thick,fill=verticalCursorColor] (\verticalCursorOne+5-0.25,7.5) rectangle (\verticalCursorOne+5+0.25,8);

           % Draw the indicator
           \draw[white,very thick] (\verticalCursorOne+5,7.45) node[anchor=south, color=white,font=\fontsize{10}{12}\selectfont] {A};

           % Draw the legend
           \draw[verticalCursorColor,very thick] (0.25,0.5) node[anchor=west, color=verticalCursorColor,font=\fontsize{10}{12}\selectfont] {\raisedtext{CurA \pgfmathprintnumber[precision=\cursorPrecision, assume math mode=true,fixed zerofill]{\verticalCursorOneValue}\ ms}};

           % If the second vertical cursor is enabled
           \ifx\verticalCursorTwo\false
           \else
             % Draw the time difference between the two vertical cursors
             \pgfmathsetmacro{\verticalCursorDiff}{\verticalCursorTwo-\verticalCursorOne}
             \pgfmathsetmacro{\verticalCursorDiffValue}{\verticalCursorDiff*\timeDiv}
             \draw[verticalCursorColor,very thick] (0.25,1.5) node[anchor=west, color=verticalCursorColor,font=\fontsize{10}{12}\selectfont] {\raisedtext{CurB - CurA \pgfmathprintnumber[precision=\cursorPrecision, assume math mode=true,fixed zerofill]{\verticalCursorDiffValue}\ ms}};
           \fi

         \fi

         % Set the value of \verticalCursorTwo
         \pgfmathsetmacro{\verticalCursorTwoValue}{\verticalCursorTwo*\timeDiv}

         % If the second vertical cursor is enabled
         \ifx\verticalCursorTwo\false
         \else
           % Draw the second vertical cursor with \verticalCursorTwo value
           \draw[verticalCursorColor,very thick,dashed] (\verticalCursorTwo+5,0) -- (\verticalCursorTwo+5,8);
           \draw[verticalCursorColor,very thick,fill=verticalCursorColor] (\verticalCursorTwo+5-0.25,7.5) rectangle (\verticalCursorTwo+5+0.25,8);

           % Draw the indicator
           \draw[white,very thick] (\verticalCursorTwo+5,7.45) node[anchor=south, color=white,font=\fontsize{10}{12}\selectfont] {B};

           % Draw the legend
           \draw[verticalCursorColor,very thick] (0.25,1) node[anchor=west, color=verticalCursorColor,font=\fontsize{10}{12}\selectfont] {\raisedtext{CurB \pgfmathprintnumber[precision=\cursorPrecision, assume math mode=true,fixed zerofill]{\verticalCursorTwoValue}\ ms}};

         \fi


         % Draw the horizontal cursors

         % Set the value of \horizontalCursorOne
         \pgfmathsetmacro{\horizontalCursorOneValue}{\horizontalCursorOne*\voltageDivOne}

         % If the first horizontal cursor is enabled
         \ifx\horizontalCursorOne\false
         \else
           % Draw the first horizontal cursor with \horizontalCursorOne value
           \draw[horizontalCursorColor,very thick,dashed] (0,\horizontalCursorOne+4) -- (10,\horizontalCursorOne+4);
           \draw[horizontalCursorColor,very thick,fill=horizontalCursorColor] (9.5,\horizontalCursorOne+4-0.25) rectangle (10.5,\horizontalCursorOne+4+0.25);

           % Draw the indicator
           \draw[white,very thick] (10,\horizontalCursorOne+4) node[anchor=east, color=white,font=\fontsize{10}{12}\selectfont] {A};

           % Draw the legend
           \draw[horizontalCursorColor,very thick] (5.25,0.5) node[anchor=west, color=horizontalCursorColor,font=\fontsize{10}{12}\selectfont] {\raisedtext{CurA \pgfmathprintnumber[precision=\cursorPrecision, assume math mode=true,fixed zerofill]{\horizontalCursorOneValue}\ V}};

           % If the second horizontal cursor is enabled
           \ifx\horizontalCursorTwo\false
           \else
             % Draw the voltage difference between the two horizontal cursors
             \pgfmathsetmacro{\horizontalCursorDiff}{\horizontalCursorTwo-\horizontalCursorOne}
             \pgfmathsetmacro{\horizontalCursorDiffValue}{\horizontalCursorDiff*\voltageDivOne}
             \draw[horizontalCursorColor,very thick] (5.25,1.5) node[anchor=west, color=horizontalCursorColor,font=\fontsize{10}{12}\selectfont] {\raisedtext{CurB - CurA \pgfmathprintnumber[precision=\cursorPrecision, assume math mode=true,fixed zerofill]{\horizontalCursorDiffValue}\ V}};
           \fi
         \fi

         % Set the value of \horizontalCursorTwo
         \pgfmathsetmacro{\horizontalCursorTwoValue}{\horizontalCursorTwo*\voltageDivOne}

         % If the second horizontal cursor is enabled
         \ifx\horizontalCursorTwo\false
         \else
           % Draw the second horizontal cursor with \horizontalCursorTwo value
           \draw[horizontalCursorColor,very thick,dashed] (0,\horizontalCursorTwo+4) -- (10,\horizontalCursorTwo+4);
           \draw[horizontalCursorColor,very thick,fill=horizontalCursorColor] (9.5,\horizontalCursorTwo+4-0.25) rectangle (10.5,\horizontalCursorTwo+4+0.25);

           % Draw the indicator
           \draw[white,very thick] (10,\horizontalCursorTwo+4) node[anchor=east, color=white,font=\fontsize{10}{12}\selectfont] {B};

           % Draw the legend
           \draw[horizontalCursorColor,very thick] (5.25,1) node[anchor=west, color=horizontalCursorColor,font=\fontsize{10}{12}\selectfont] {\raisedtext{CurB \pgfmathprintnumber[precision=\cursorPrecision, assume math mode=true,fixed zerofill]{\horizontalCursorTwoValue}\ V}};

         \fi

         % End xyMode test
       \fi

     \end{scope}

   \end{tikzpicture}
 }
}