Edgewall Software

TracDev/Proposals/Announcer: pgf-umlsd.sty

File pgf-umlsd.sty, 7.8 KB (added by rcorsaro, 2 years ago)
Line 
1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2% Start of pgf-umlsd.sty
3%
4% Some macros for UML Sequence Diagrams.
5%
6% Author: Xu Yuan <xuyuan.cn@gmail.com>, Southeast University, China
7%
8% History:
9% v0.2 2008/03/20 create project at http://pgf-umlsd.googlecode.com/
10%      - use `shadows' library
11%      Thanks for Dr. Ludger Humbert's <humbert@uni-wuppertal.de> feedback!
12%      - reduce the parameter numbers, the user can write the content
13%      of instance (such as no colon)
14%      - the user can redefine the `inststyle'
15%      - new option: switch underlining of the instance text
16%      - new option: switch rounded corners
17% v0.1 2008/01/25 first release at http://www.fauskes.net/pgftikzexamples/
18
19\NeedsTeXFormat{LaTeX2e}[1999/12/01]
20\ProvidesPackage{pgf-umlsd}[2008/03/20 v0.2 Some LaTeX macros for UML
21Sequence Diagrams.]
22
23% Options
24% ? the instance name under line ?
25\newif\ifpgfumlsdunderline\pgfumlsdunderlinetrue
26\DeclareOption{underline}{\pgfumlsdunderlinetrue}
27\DeclareOption{underline=true}{\pgfumlsdunderlinetrue}
28\DeclareOption{underline=false}{\pgfumlsdunderlinefalse}
29% ? the instance box with rounded corners ?
30\newif\ifpgfumlsdroundedcorners\pgfumlsdroundedcornersfalse
31\DeclareOption{roundedcorners}{\pgfumlsdroundedcornerstrue}
32\DeclareOption{roundedcorners=true}{\pgfumlsdroundedcornerstrue}
33\DeclareOption{roundedcorners=false}{\pgfumlsdroundedcornersfalse}
34\ProcessOptions
35
36% declare layers
37\pgfdeclarelayer{background}
38\pgfdeclarelayer{threadground}
39\pgfsetlayers{background,threadground,main}
40
41% new counters
42\newcounter{preinst}
43\newcounter{instnum}
44\newcounter{threadnum}
45\newcounter{seqlevel} % level
46\newcounter{callevel}
47\newcounter{looplevel}
48
49% new an instance
50% Example:
51% \newinst[edge distance]{var}{name:class}
52\newcommand{\newinst}[3][0.2]{
53  \stepcounter{instnum}
54  \path (inst\thepreinst.east)+(#1,0) node[inststyle] (inst\theinstnum)
55  {\ifpgfumlsdunderline
56    \underline{#3}
57  \else
58  #3
59  \fi};
60  \path (inst\theinstnum)+(0,-0.5*\unitfactor) node (#2) {};
61  \tikzstyle{instcolor#2}=[]
62  \stepcounter{preinst}
63}
64
65% new an instance thread
66% Example:
67% \newinst[color]{var}{name}{class}
68\newcommand{\newthread}[3][gray!30]{
69  \newinst{#2}{#3}
70  \stepcounter{threadnum}
71  \node[below of=inst\theinstnum,node distance=0.8cm] (thread\thethreadnum) {};
72  \tikzstyle{threadcolor\thethreadnum}=[fill=#1]
73  \tikzstyle{instcolor#2}=[fill=#1]
74}
75
76% draw running (thick) line, should not call directly
77\newcommand*{\drawthread}[2]{
78  \begin{pgfonlayer}{threadground}
79    \draw[threadstyle] (#1.west) -- (#1.east) -- (#2.east) -- (#2.west) -- cycle;
80  \end{pgfonlayer}
81}
82
83% a function call
84% Example:
85% \begin{call}[height]{caller}{function}{callee}{return}
86% \end{call}
87\newenvironment{call}[5][1]{
88  \stepcounter{seqlevel}
89  \stepcounter{callevel} % push
90  \path
91  (#2)+(0,-\theseqlevel*\unitfactor-0.7*\unitfactor) node (cf\thecallevel) {}
92  (#4.\threadbias)+(0,-\theseqlevel*\unitfactor-0.7*\unitfactor) node (ct\thecallevel) {};
93 
94  \draw[->,>=triangle 60] ({cf\thecallevel}) -- (ct\thecallevel)
95  node[midway, above] {\small #3};
96  \def\l\thecallevel{#1}
97  \def\f\thecallevel{#2}
98  \def\t\thecallevel{#4}
99  \def\returnvalue{#5}
100  \tikzstyle{threadstyle}+=[instcolor#2]
101}
102{
103  \addtocounter{seqlevel}{\l\thecallevel}
104  \path
105  (\f\thecallevel)+(0,-\theseqlevel*\unitfactor-0.7*\unitfactor) node (rf\thecallevel) {}
106  (\t\thecallevel.\threadbias)+(0,-\theseqlevel*\unitfactor-0.7*\unitfactor) node (rt\thecallevel) {};
107  \draw[dashed,->,>=angle 60] ({rt\thecallevel}) -- (rf\thecallevel)
108  node[midway, above]{\small \returnvalue};
109  \drawthread{ct\thecallevel}{rt\thecallevel}
110  \addtocounter{callevel}{-1} % pop
111}
112
113% a function do not need call others
114% Example:
115% \begin{callself}[height]{caller}{function}{return}
116% \end{callself}
117\newenvironment{callself}[4][1]{
118  \stepcounter{seqlevel}
119  \stepcounter{callevel} % push
120  \path
121  (#2)+(0,-\theseqlevel*\unitfactor-0.7*\unitfactor) node (sc\thecallevel) {}
122  ({sc\thecallevel}.east)+(0,-0.33*\unitfactor) node (scb\thecallevel) {};
123
124  \draw[->,>=triangle 60] ({sc\thecallevel}.east) -- ++(0.8,0)
125  node[near start, above right] {\small #3} -- ++(0,-0.33*\unitfactor)
126  -- (scb\thecallevel);
127  \def\l\thecallevel{#1}
128  \def\f\thecallevel{#2}
129  \def\returnvalue{#4}
130  \tikzstyle{threadstyle}+=[instcolor#2]
131}{
132  \addtocounter{seqlevel}{\l\thecallevel}
133  \path (\f\thecallevel)+(0,-\theseqlevel*\unitfactor-0.33*\unitfactor) node
134  (sct\thecallevel) {};
135
136  \draw[dashed,->,>=angle 60] ({sct\thecallevel}.east) node
137  (sce\thecallevel) {} -- ++(0.8,0) -- node[midway, right]{\small \returnvalue} ++(0,-0.33*\unitfactor) -- ++(-0.8,0);
138  \drawthread{scb\thecallevel}{sce\thecallevel}
139  \addtocounter{callevel}{-1} % pop
140}
141
142% message between threads
143% Example:
144% \mess{sender}{message content}{receiver}
145\newcommand{\mess}[3]{
146  \stepcounter{seqlevel}
147  \path
148  (#1)+(0,-\theseqlevel*\unitfactor-0.7*\unitfactor) node (messbeg) {}
149  (#3)+(0,-\theseqlevel*\unitfactor-0.7*\unitfactor) node (messend) {};
150  \draw[->,>=angle 60] (messbeg) -- (messend) node[midway, above] {\small #2};
151}
152
153% In the situation of multi-threads, some objects are called at the
154% same time. Currently, we have to adjust the bias of thread line
155% manually. Possible parameters are: center, west, east
156\newcommand{\setthreadbias}[1]{\global\def\threadbias{#1}}
157
158% In the situation of multi-threads, some events happen at the same
159% time. Currently, we have to adjust the level(time) of events
160% manually. This function makes the call eariler.
161\newcommand{\prelevel}{\addtocounter{seqlevel}{-1}}
162
163% a loop box with caption
164% \begin{sdloop}[caption background color]{caption}
165% \end{sdlopp}
166\newenvironment{sdloop}[2][white]{
167  \stepcounter{seqlevel}
168  \stepcounter{looplevel} % push
169  \coordinate (loopbeg\thelooplevel) at (0,-\theseqlevel*\unitfactor-0.5*\unitfactor);
170  \def\loopcolor\thelooplevel{#1}
171  \def\loopname\thelooplevel{#2}
172  \begin{pgfinterruptboundingbox}
173}{
174  \coordinate (loopend) at (0,-\theseqlevel*\unitfactor-1.4*\unitfactor);
175  \path (current bounding box.east)+(0.2,0) node (boxeast) {}
176  (current bounding box.west |- {loopbeg\thelooplevel}) + (-0.2,0)
177  node (nw) {};
178  \draw (nw) rectangle (boxeast |- loopend); %se
179
180  % title
181  \node[loopstyle] (looptitle) at (nw) {\loopname\thelooplevel};
182  \path (looptitle.south east) + (0,0.2) node (set) {}
183  (looptitle.south east) + (-0.2,0) node (seb) {};
184  \draw[fill=\loopcolor\thelooplevel] (looptitle.north west) -- (looptitle.north east) --
185  (set.center) -- (seb.center) -- (looptitle.south west) -- cycle;
186  \node[loopstyle] (looptitle) at (nw) {\loopname\thelooplevel};
187
188  \end{pgfinterruptboundingbox}
189  \addtocounter{looplevel}{-1} % pop
190}
191
192% the environment of sequence diagram
193\newenvironment{sequencediagram}{
194  \begin{tikzpicture}
195    \setlength{\unitlength}{1cm}
196    \tikzstyle{sequence}=[coordinate]
197    \tikzstyle{inststyle}=[rectangle, draw, anchor=west, minimum
198    height=0.8cm, minimum width=1.6cm, fill=white,
199    drop shadow={opacity=1,fill=black}]
200    \ifpgfumlsdroundedcorners
201    \tikzstyle{inststyle}+=[rounded corners=3mm]
202    \fi
203    \tikzstyle{loopstyle}=[anchor=north west]
204    \global\def\unitfactor{0.6}
205    \global\def\threadbias{center}
206    % reset counters
207    \setcounter{preinst}{0}
208    \setcounter{instnum}{0}
209    \setcounter{threadnum}{0}
210    \setcounter{seqlevel}{0}
211    \setcounter{callevel}{0}
212    \setcounter{looplevel}{0}
213
214    % origin
215    \node[coordinate] (inst0) {};
216}
217{
218  \begin{pgfonlayer}{background}
219    \foreach \t in {1,...,\theinstnum}{
220      \draw[dotted] (inst\t) -- ++(0,-\theseqlevel*\unitfactor-2.2*\unitfactor);
221    }
222    \foreach \t in {1,...,\thethreadnum}{
223      \path (thread\t)+(0,-\theseqlevel*\unitfactor-0.1*\unitfactor) node (threadend) {};
224      \tikzstyle{threadstyle}+=[threadcolor\t]
225      \drawthread{thread\t}{threadend}
226    }
227  \end{pgfonlayer}
228\end{tikzpicture}}
229
230
231%%% End of pgf-umlsd.sty
232%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%