Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
latextemplates
GitHub Repository: latextemplates/scientific-thesis-template
Path: blob/main/tikz-uml.sty
340 views
1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
% Start of tikz-uml.sty
3
%
4
% Some macros for UML Diagrams.
5
% Home page of project :
6
% Author: Nicolas Kielbasiewicz
7
% Style from :
8
% Fixed by Nicolas Kielbasiewicz ([email protected]) in march 2016 to compile with pgf 3.00
9
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10
%
11
\NeedsTeXFormat{LaTeX2e}[1995/12/01]%
12
\ProvidesPackage{tikz-uml}[2011/01/26]%
13
%
14
\RequirePackage{ifthen}%
15
\RequirePackage{tikz}%
16
\RequirePackage{xstring}%
17
\RequirePackage{calc}%
18
\RequirePackage{pgfopts}%
19
\usetikzlibrary{backgrounds,arrows,shapes,fit,shadows,decorations.markings}%
20
%
21
\def\tikzumlPackageLayersNum{3}%
22
\pgfkeys{/tikzuml/options/.cd, packageLayers/.initial=3}%
23
\pgfkeys{/tikzuml/options/.cd, packageLayers/.store in=\tikzumlPackageLayersNum}%
24
\def\tikzumlStateLayersNum{3}%
25
\pgfkeys{/tikzuml/options/.cd, stateLayers/.initial=3}%
26
\pgfkeys{/tikzuml/options/.cd, stateLayers/.store in=\tikzumlStateLayersNum}%
27
\def\tikzumlFragmentLayersNum{3}%
28
\pgfkeys{/tikzuml/options/.cd, fragmentLayers/.initial=3}%
29
\pgfkeys{/tikzuml/options/.cd, fragmentLayers/.store in=\tikzumlFragmentLayersNum}%
30
\def\tikzumlComponentLayersNum{3}%
31
\pgfkeys{/tikzuml/options/.cd, componentLayers/.initial=3}%
32
\pgfkeys{/tikzuml/options/.cd, componentLayers/.store in=\tikzumlComponentLayersNum}%
33
%
34
\ProcessPgfOptions{/tikzuml/options}%
35
%
36
\def\pgfsetlayersArg{background}%
37
\pgfdeclarelayer{background}%
38
\newcounter{tikzumlPackageLayers}%
39
\loop \pgfdeclarelayer{package\thetikzumlPackageLayers}%
40
\xdef\pgfsetlayersArg{\pgfsetlayersArg,package\thetikzumlPackageLayers}%
41
\ifnum\tikzumlPackageLayersNum>\thetikzumlPackageLayers%
42
\stepcounter{tikzumlPackageLayers}%
43
\repeat%
44
%
45
\newcounter{tikzumlFragmentLayers}%
46
\loop \pgfdeclarelayer{fragment\thetikzumlFragmentLayers}%
47
\xdef\pgfsetlayersArg{\pgfsetlayersArg,fragment\thetikzumlFragmentLayers}%
48
\ifnum\tikzumlFragmentLayersNum>\thetikzumlFragmentLayers%
49
\stepcounter{tikzumlFragmentLayers}%
50
\repeat%
51
%
52
\newcounter{tikzumlStateLayers}%
53
\loop \pgfdeclarelayer{state\thetikzumlStateLayers}%
54
\xdef\pgfsetlayersArg{\pgfsetlayersArg,state\thetikzumlStateLayers}%
55
\ifnum\tikzumlStateLayersNum>\thetikzumlStateLayers%
56
\stepcounter{tikzumlStateLayers}%
57
\repeat%
58
%
59
\newcounter{tikzumlComponentLayers}%
60
\loop \pgfdeclarelayer{component\thetikzumlComponentLayers}%
61
\xdef\pgfsetlayersArg{\pgfsetlayersArg,component\thetikzumlComponentLayers}%
62
\ifnum\tikzumlComponentLayersNum>\thetikzumlComponentLayers%
63
\stepcounter{tikzumlComponentLayers}%
64
\repeat%
65
%
66
\pgfdeclarelayer{lifelines}%
67
\pgfdeclarelayer{activity}%
68
\pgfdeclarelayer{connections}%
69
\xdef\pgfsetlayersArg{\pgfsetlayersArg,lifelines,activity,connections,main}%
70
\pgfsetlayers{\pgfsetlayersArg}%
71
%
72
\pgfkeys{/tikzuml/.cd, text/.initial=black, draw/.initial=black, font/.initial=\small,%
73
x/.initial=0, y/.initial=0,%
74
package type/.initial=tikzumlEmpty, fill package/.initial=blue!20,%
75
class width/.initial=10ex, simple interface width/.initial=4ex, class type/.initial=class, fill class/.initial=yellow!20, fill template/.initial=yellow!2,%
76
narynode width/.initial=6ex,%
77
relation geometry/.initial=--, relation angle1/.initial=-30, relation angle2/.initial=30, relation loopsize/.initial=3em, relation weight/.initial=0.5, relation pos1/.initial=0.2, relation pos2/.initial=0.8, relation pos stereo/.initial=0.5,%
78
note width/.initial=3cm, fill note/.initial=green!20,%
79
fill system/.initial=white,%
80
fill usecase/.initial=blue!20,%
81
actor below/.initial=0.5cm,%
82
state join width/.initial=3ex,%
83
state decision width/.initial=3ex,%
84
state initial width/.initial=5ex,%
85
state final width/.initial=5.5ex,%
86
state enter width/.initial=5ex,%
87
state exit width/.initial=5ex,%
88
state end width/.initial=5ex,%
89
state history width/.initial=5ex,%
90
state deep history width/.initial=5ex,%
91
state width/.initial=8ex, fill state/.initial=yellow!20,%
92
object stereo/.initial=object, fill object/.initial=yellow!20,%
93
call dt/.initial=tikzumlEmpty, call padding/.initial=2, call type/.initial=synchron, fill call/.initial=white,%
94
fragment type/.initial=opt, fragment inner xsep/.initial=1, fragment inner ysep/.initial=1, fill fragment/.initial= none,%
95
create call dt/.initial=4,%
96
component width/.initial=8ex, fill component/.initial= yellow!20,%
97
required interface distance/.initial=2.5cm, required interface width/.initial=1em, required interface padding/.initial=1cm,%
98
provided interface distance/.initial=3cm, provided interface width/.initial=1em, provided interface padding/.initial=1cm,%
99
port width/.initial=1ex, fill port/.initial= yellow!20,%
100
fill assembly connector/.initial= white,%
101
.unknown/.code={%
102
\let\keyname=\pgfkeyscurrentname%
103
\let\keyvalue=\pgfkeyscurrentvalue%
104
\errmessage{TIKZUML ERROR : in tikzuml global, invalid option \keyname}%
105
}%
106
}%
107
%
108
\pgfkeys{/tikzuml/.cd, text/.get=\tikzumlDefaultTextColor, draw/.get=\tikzumlDefaultDrawColor, font/.get=\tikzumlDefaultFont,%
109
x/.get=\tikzumlDefaultX, y/.get=\tikzumlDefaultY,%
110
package type/.get=\tikzumlPackageDefaultType, fill package/.get=\tikzumlPackageDefaultFillColor,%
111
class width/.get=\tikzumlClassDefaultWidth, simple interface width/.get=\tikzumlSimpleInterfaceDefaultWidth, class type/.get=\tikzumlClassDefaultType, fill class/.get=\tikzumlClassDefaultFillColor, fill template/.get=\tikzumlClassTemplateFillColorDefaultFillColor,%
112
narynode width/.get=\tikzumlNaryNodeDefaultWidth,%
113
relation geometry/.get=\tikzumlRelationDefaultGeometry, relation angle1/.get=\tikzumlRelationDefaultAngleO, relation angle2/.get=\tikzumlRelationDefaultAngleT, relation loopsize/.get=\tikzumlRelationDefaultLoopSize, relation weight/.get=\tikzumlRelationDefaultWeight, relation pos1/.get=\tikzumlRelationDefaultPosO, relation pos2/.get=\tikzumlRelationDefaultPosT, relation pos stereo/.get=\tikzumlRelationDefaultPosStereo,%
114
note width/.get=\tikzumlNoteDefaultWidth, fill note/.get=\tikzumlNoteDefaultFillColor,%
115
fill system/.get=\tikzumlSystemDefaultFillColor,%
116
fill usecase/.get=\tikzumlUseCaseDefaultFillColor,%
117
actor below/.get=\tikzumlActorDefaultBelow,%
118
state join width/.get=\tikzumlStateJoinDefaultWidth,%
119
state decision width/.get=\tikzumlStateDecisionDefaultWidth,%
120
state initial width/.get=\tikzumlStateInitialDefaultWidth,%
121
state final width/.get=\tikzumlStateFinalDefaultWidth,%
122
state enter width/.get=\tikzumlStateEnterDefaultWidth,%
123
state exit width/.get=\tikzumlStateExitDefaultWidth,%
124
state end width/.get=\tikzumlStateEndDefaultWidth,%
125
state history width/.get=\tikzumlStateHistoryDefaultWidth,%
126
state deep history width/.get=\tikzumlStateDeepHistoryDefaultWidth,%
127
state width/.get=\tikzumlStateDefaultWidth, fill state/.get=\tikzumlStateDefaultFillColor,%
128
object stereo/.get=\tikzumlObjectDefaultStereo, fill object/.get=\tikzumlObjectDefaultFillColor,%
129
call dt/.get=\tikzumlCallDefaultDT, call padding/.get=\tikzumlCallDefaultPadding, call type/.get=\tikzumlCallDefaultType, fill call/.get=\tikzumlCallDefaultFillColor,%
130
fragment type/.get=\tikzumlFragmentDefaultType, fragment inner xsep/.get=\tikzumlFragmentDefaultXSep, fragment inner ysep/.get=\tikzumlFragmentDefaultYSep, fill fragment/.get=\tikzumlFragmentDefaultFillColor,%
131
create call dt/.get=\tikzumlCreateCallDefaultDT,%
132
component width/.get=\tikzumlComponentDefaultWidth, fill component/.get=\tikzumlComponentDefaultFillColor,%
133
required interface distance/.get=\tikzumlRequiredInterfaceDefaultDistance, required interface width/.get=\tikzumlRequiredInterfaceDefaultWidth, required interface padding/.get=\tikzumlRequiredInterfaceDefaultPadding,%
134
provided interface distance/.get=\tikzumlProvidedInterfaceDefaultDistance, provided interface width/.get=\tikzumlProvidedInterfaceDefaultWidth, provided interface padding/.get=\tikzumlProvidedInterfaceDefaultPadding,%
135
port width/.get=\tikzumlPortDefaultWidth, fill port/.get=\tikzumlPortDefaultFillColor,%
136
fill assembly connector/.get=\tikzumlAssemblyConnectorDefaultFillColor%
137
}%
138
%
139
% utility : change default colors
140
\newcommand{\tikzumlset}[1]{%
141
\pgfkeys{/tikzuml/.cd,#1}%
142
\pgfkeys{/tikzuml/.cd, text/.get=\tikzumlDefaultTextColor, draw/.get=\tikzumlDefaultDrawColor, font/.get=\tikzumlDefaultFont,%
143
x/.get=\tikzumlDefaultX, y/.get=\tikzumlDefaultY,%
144
package type/.get=\tikzumlPackageDefaultType, fill package/.get=\tikzumlPackageDefaultFillColor,%
145
class width/.get=\tikzumlClassDefaultWidth, simple interface width/.get=\tikzumlSimpleInterfaceDefaultWidth, class type/.get=\tikzumlClassDefaultType, fill class/.get=\tikzumlClassDefaultFillColor, fill template/.get=\tikzumlClassTemplateFillColorDefaultFillColor,%
146
narynode width/.get=\tikzumlNaryNodeWidth,%
147
relation geometry/.get=\tikzumlRelationDefaultGeometry, relation angle1/.get=\tikzumlRelationDefaultAngleO, relation angle2/.get=\tikzumlRelationDefaultAngleT, relation loopsize/.get=\tikzumlRelationDefaultLoopSize, relation weight/.get=\tikzumlRelationDefaultWeight, relation pos1/.get=\tikzumlRelationDefaultPosO, relation pos2/.get=\tikzumlRelationDefaultPosT, relation pos stereo/.get=\tikzumlRelationDefaultPosStereo,%
148
note width/.get=\tikzumlNoteDefaultWidth, fill note/.get=\tikzumlNoteDefaultFillColor,%
149
fill system/.get=\tikzumlSystemDefaultFillColor,%
150
fill usecase/.get=\tikzumlUseCaseDefaultFillColor,%
151
actor below/.get=\tikzumlActorDefaultBelow,%
152
state join width/.get=\tikzumlStateJoinDefaultWidth,%
153
state decision width/.get=\tikzumlStateDecisionDefaultWidth,%
154
state initial width/.get=\tikzumlStateInitialDefaultWidth,%
155
state final width/.get=\tikzumlStateFinalDefaultWidth,%
156
state enter width/.get=\tikzumlStateEnterDefaultWidth,%
157
state exit width/.get=\tikzumlStateExitDefaultWidth,%
158
state end width/.get=\tikzumlStateEndDefaultWidth,%
159
state history width/.get=\tikzumlStateHistoryDefaultWidth,%
160
state deep history width/.get=\tikzumlStateDeepHistoryDefaultWidth,%
161
state width/.get=\tikzumlStateDefaultWidth, fill state/.get=\tikzumlStateDefaultFillColor,%
162
object stereo/.get=\tikzumlObjectDefaultStereo, fill object/.get=\tikzumlObjectDefaultFillColor,%
163
call dt/.get=\tikzumlCallDefaultDT, call padding/.get=\tikzumlCallDefaultPadding, call type/.get=\tikzumlCallDefaultType, fill call/.get=\tikzumlCallDefaultFillColor,%
164
fragment type/.get=\tikzumlFragmentDefaultType, fragment inner xsep/.get=\tikzumlFragmentDefaultXSep, fragment inner ysep/.get=\tikzumlFragmentDefaultYSep, fill fragment/.get=\tikzumlFragmentDefaultFillColor,%
165
create call dt/.get=\tikzumlCreateCallDT,%
166
component width/.get=\tikzumlComponentDefaultWidth, fill component/.get=\tikzumlComponentDefaultFillColor,%
167
required interface distance/.get=\tikzumlRequiredInterfaceDefaultDistance, required interface width/.get=\tikzumlRequiredInterfaceDefaultWidth, required interface padding/.get=\tikzumlRequiredInterfaceDefaultPadding,%
168
provided interface distance/.get=\tikzumlProvidedInterfaceDefaultDistance, provided interface width/.get=\tikzumlProvidedInterfaceDefaultWidth, provided interface padding/.get=\tikzumlProvidedInterfaceDefaultPadding,%
169
port width/.get=\tikzumlPortDefaultWidth, fill port/.get=\tikzumlPortDefaultFillColor,%
170
fill assembly connector/.get=\tikzumlAssemblyConnectorDefaultFillColor%
171
}%
172
}%
173
%
174
% define a point
175
% arg : node/coordinates of the point
176
\newcommand{\umlpoint}[1]{%
177
\begin{pgfonlayer}{connections}%
178
\node[tikzuml control nodes style] at (#1) {};%
179
\end{pgfonlayer}%
180
}%
181
%
182
\newcommand{\tikzumlskipescape}[3][_]{%
183
\begingroup%
184
\def\_{#1}\edef\x{\endgroup%
185
\def\noexpand\csname #3\endcsname{#2}}\x%
186
}%
187
%
188
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
189
% class diagrams %
190
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
191
%
192
\pgfkeys{/tikzuml/relation/.cd, attr1/.style args={#1|#2}{arg1=#1, mult1=#2},%
193
attr2/.style args={#1|#2}{arg2=#1, mult2=#2},%
194
attr/.style args={#1|#2}{arg=#1, mult=#2},%
195
recursive/.style args={#1|#2|#3}{angle1=#1, angle2=#2, loopsize=#3},%
196
anchors/.style args={#1 and #2}{anchor1=#1, anchor2=#2},%
197
recursive direction/.style args={#1 to #2}{recursive direction start=#1, recursive direction end=#2}%
198
}%
199
%
200
\pgfkeys{/tikzuml/note/.cd, anchors/.style args={#1 and #2}{anchor1=#1, anchor2=#2}}%
201
%
202
\tikzstyle{tikzuml simpleclass style}=[rectangle, minimum height=2em, node distance=2em]%
203
\tikzstyle{tikzuml simpleinterface style}=[circle, minimum height=1em, node distance=1em]%
204
\tikzstyle{tikzuml class style}=[rectangle split, rectangle split parts=3, rectangle split part align={center, left, left}, minimum height=2em, node distance=2em]%
205
\tikzstyle{tikzuml narynode style}=[diamond]%
206
\tikzstyle{tikzuml template style}=[dashed, inner ysep=0.5em, inner xsep=1ex]%
207
\tikzstyle{tikzuml control nodes style}=[fill=black, inner sep=1.5pt, circle]%
208
%
209
\tikzstyle{tikzuml association style}=[color=\tikzumlDefaultDrawColor, -]%
210
\tikzstyle{tikzuml bidirectional association style}=[color=\tikzumlDefaultDrawColor, angle45-angle45]%
211
\tikzstyle{tikzuml unidirectional association style}=[color=\tikzumlDefaultDrawColor, -angle 45]%
212
\tikzstyle{tikzuml aggregation style}=[color=\tikzumlDefaultDrawColor, open diamond-]%
213
\tikzstyle{tikzuml unidirectional aggregation style}=[color=\tikzumlDefaultDrawColor, open diamond-angle 45]%
214
\tikzstyle{tikzuml composition style}=[color=\tikzumlDefaultDrawColor, diamond-]%
215
\tikzstyle{tikzuml unidirectional composition style}=[color=\tikzumlDefaultDrawColor, diamond-angle 45]%
216
\tikzstyle{tikzuml nesting style}=[color=\tikzumlDefaultDrawColor]%
217
\tikzstyle{tikzuml dependency style}=[color=\tikzumlDefaultDrawColor, -angle 45, dashed]%
218
\tikzstyle{tikzuml import style}=[color=\tikzumlDefaultDrawColor, -angle 45, dashed]%
219
\tikzstyle{tikzuml inherit style}=[color=\tikzumlDefaultDrawColor, -open triangle 45]%
220
\tikzstyle{tikzuml implements style}=[color=\tikzumlDefaultDrawColor, -open triangle 45, dashed]%
221
%
222
\pgfkeys{/tikzuml/assemblyconnectorrelation/.cd, anchors/.style args={#1 and #2}{anchor1=#1, anchor2=#2}}%
223
%
224
\newcounter{tikzumlPackageClassNum}%
225
\newcounter{tikzumlPackageSubPackageNum}%
226
\newcounter{tikzumlRelationNum}%
227
\setcounter{tikzumlRelationNum}{1}%
228
\newcounter{tikzumlNoteNum}%
229
\setcounter{tikzumlNoteNum}{1}%
230
%
231
\newcounter{pos}%
232
\newcounter{posT}%
233
\newcounter{posStereo}%
234
%
235
\newcounter{tikzumlPackageLevel}%
236
\setcounter{tikzumlPackageLevel}{0}%
237
%
238
\newif\iftikzumlpackageSimpleStyle%
239
\newif\iftikzumlclassSimpleStyle%
240
\newif\iftikzumlclassCircleShape%
241
\newif\iftikzumlpackageWithoutCoords%
242
\newif\iftikzumlclassWithoutCoords%
243
\newif\iftikzumlassocclassWithoutCoords%
244
\newif\iftikzumlnoteWithoutCoords%
245
%
246
% define a uml package
247
% arg : package name
248
% optional : x, y: coordinates of the package
249
% type: stereotype of the package
250
% name: name of the package node
251
% draw, fill, text: colors
252
% style: to manage every default TikZ option
253
% no coords: to tell that the package position is defined relatively
254
% to another node (automatically used with TikZ options above, below, left, right, below left, ...)
255
\newenvironment{umlpackage}[2][]{%
256
\pgfkeys{/tikzuml/package/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, style/.style={},%
257
name/.initial=tikzumlEmpty, type/.initial=\tikzumlPackageDefaultType, draw/.initial=\tikzumlDefaultDrawColor,%
258
fill/.initial=\tikzumlPackageDefaultFillColor, text/.initial=\tikzumlDefaultTextColor,%
259
no coords/.is if=tikzumlpackageWithoutCoords,%
260
no coords=false,%
261
.unknown/.code={%
262
\let\keyname=\pgfkeyscurrentname%
263
\let\keyvalue=\pgfkeyscurrentvalue%
264
\ifthenelse{\equal{\keyname}{above}\OR%
265
\equal{\keyname}{left}\OR%
266
\equal{\keyname}{below}\OR%
267
\equal{\keyname}{right}\OR%
268
\equal{\keyname}{above left}\OR%
269
\equal{\keyname}{above right}\OR%
270
\equal{\keyname}{below left}\OR%
271
\equal{\keyname}{below right}}{%
272
\IfSubStr{\keyvalue}{ of }{%
273
\pgfkeys{/tikzuml/package/.cd, no coords}%
274
}{}%
275
}{}%
276
\ifx\keyvalue\pgfkeysnovalue%
277
\pgfkeys{/tikzuml/package/.cd, style/.append style/.expand once={\keyname}}%
278
\else%
279
\pgfkeys{/tikzuml/package/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
280
\fi%
281
%\errmessage{TIKZUML ERROR : in umlpackage, invalid option \keyname}%
282
}%
283
}%
284
\pgfkeys{/tikzuml/package/.cd, #1}%
285
\pgfkeys{/tikzuml/package/.cd, x/.get=\tikzumlPackageXShift, y/.get=\tikzumlPackageYShift, name/.get=\tikzumlPackageName, type/.get=\tikzumlPackageTypeTmp,%
286
draw/.get=\tikzumlPackageDrawColor, fill/.get=\tikzumlPackageFillColor,%
287
text/.get=\tikzumlPackageTextColor%
288
}%
289
%
290
291
%
292
\ifthenelse{\equal{\tikzumlPackageTypeTmp}{tikzumlEmpty}}{%
293
\def\tikzumlPackageType{}%
294
}{%
295
\expandafter\def\expandafter\tikzumlPackageType\expandafter{$\ll$\tikzumlPackageTypeTmp$\gg$ \\}%
296
}%
297
%
298
\ifnum\thetikzumlPackageLevel>0%
299
\let\tikzumlPackage@nameold\tikzumlPackage@fitname%
300
\def\tikzumlPackage@name{#2}%
301
\begingroup%
302
\def\_{@}\edef\x{\endgroup%
303
\def\noexpand\tikzumlPackage@fitname{\tikzumlPackage@name}}\x%
304
\let\tikzumlPackage@parentold\tikzumlPackage@parent%
305
\edef\tikzumlPackage@parent{\tikzumlPackage@parentold @@\tikzumlPackage@nameold}%
306
\else%
307
\def\tikzumlPackage@parent{}%
308
\def\tikzumlPackage@name{#2}%
309
\begingroup%
310
\def\_{@}\edef\x{\endgroup%
311
\def\noexpand\tikzumlPackage@fitname{\tikzumlPackage@name}}\x%
312
\fi%
313
%
314
\let\tikzumlPackage@nodeNameold\tikzumlPackage@nodeName%
315
%
316
\begingroup%
317
\def\_{_}\edef\x{\endgroup%
318
\def\noexpand\tikzumlPackage@nodeName{\tikzumlPackage@name}}\x%
319
%
320
\ifthenelse{\equal{\tikzumlPackageName}{tikzumlEmpty}}{}{%
321
\def\tikzumlPackage@nodeName{\tikzumlPackageName}%
322
}%
323
%
324
\StrSubstitute{\tikzumlPackage@nodeName}{.}{@POINT@}{\tikzumlPackage@nodeName}%
325
%
326
\expandafter\gdef\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname{}%
327
%
328
\setcounter{tikzumlPackageClassNum}{0}%
329
\setcounter{tikzumlPackageSubPackageNum}{0}%
330
\stepcounter{tikzumlPackageLevel}%
331
%
332
\begin{scope}[xshift=\tikzumlPackageXShift cm, yshift=\tikzumlPackageYShift cm]%
333
}{%
334
\addtocounter{tikzumlPackageLevel}{-1}%
335
\begin{pgfonlayer}{package\thetikzumlPackageLevel}%
336
%
337
% if contains no class, and not simple, one define a fictive node to enable the fit option
338
\ifnum\c@tikzumlPackageClassNum=0%
339
\ifnum\c@tikzumlPackageSubPackageNum=0%
340
\iftikzumlpackageWithoutCoords%
341
\node[inner sep=1.5ex, /tikzuml/package/style] (\tikzumlPackage@nodeName-root) {\phantom{\tikzumlPackage@nodeName}};%
342
\else%
343
\node[inner sep=1.5ex, /tikzuml/package/style] (\tikzumlPackage@nodeName-root) at (0,0) {\phantom{\tikzumlPackage@nodeName}};%
344
\fi%
345
\expandafter\xdef\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname{(\tikzumlPackage@nodeName-root)}%
346
\fi%
347
\fi%
348
%
349
\ifnum\c@tikzumlPackageLevel>0%
350
\def\tikzumlPackageFitTmp{\csname tikzumlPackageFit\tikzumlPackage@parent\endcsname}%
351
\expandafter\xdef\csname tikzumlPackageFit\tikzumlPackage@parent\endcsname{\tikzumlPackageFitTmp (\tikzumlPackage@nodeName) (\tikzumlPackage@nodeName-caption)}%
352
\stepcounter{tikzumlPackageSubPackageNum}%
353
\fi%
354
%
355
\node[draw=\tikzumlPackageDrawColor, fill=\tikzumlPackageFillColor, text=\tikzumlPackageTextColor, font=\tikzumlDefaultFont, inner sep=1.5ex, /tikzuml/package/style, fit = \csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname] (\tikzumlPackage@nodeName) {};%
356
\node[draw=\tikzumlPackageDrawColor, fill=\tikzumlPackageFillColor, text=\tikzumlPackageTextColor, font=\tikzumlDefaultFont, minimum height=1.5em, outer ysep=-0.3, anchor=south west] (\tikzumlPackage@nodeName-caption) at (\tikzumlPackage@nodeName.north west) {\begin{tabular}{c} \tikzumlPackageType \textbf{\tikzumlPackage@name}\end{tabular}};%
357
\end{pgfonlayer}%
358
\end{scope}%
359
}%
360
%
361
% shortcut to define an empty package
362
\newcommand{\umlemptypackage}[2][]{\begin{umlpackage}[#1]{#2} \end{umlpackage}}%
363
%
364
% define a uml class
365
% args : name of the class
366
% attributes of the class
367
% operations of the class
368
% optional : x, y: coordinates of the class
369
% width: of the class node
370
% type: type of class (class, interface, typedef, enum)
371
% tags: tagged values of class
372
% template: template parameters
373
% simple: if used, class is empty and drawn with a rectangle
374
% circle: if used with simple, class is empty and drawn with a circle
375
% draw, fill, fill template, and text: colors
376
% style: to manage every default TikZ option
377
% no coords: to tell that the class position is defined relatively
378
% to another node (automatically used with TikZ options above, below, left, right, below left, ...)
379
\newcommand{\umlclass}[4][]{%
380
\pgfkeys{/tikzuml/class/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlClassDefaultWidth, type/.initial=\tikzumlClassDefaultType,%
381
tags/.initial={}, style/.style={},%
382
template/.initial={}, name/.initial=tikzumlEmpty,%
383
draw/.initial=\tikzumlDefaultDrawColor,%
384
fill template/.initial=\tikzumlClassTemplateFillColorDefaultFillColor,%
385
fill/.initial=\tikzumlClassDefaultFillColor,%
386
text/.initial=\tikzumlDefaultTextColor,%
387
simple/.is if=tikzumlclassSimpleStyle, circle/.is if=tikzumlclassCircleShape, no coords/.is if=tikzumlclassWithoutCoords,%
388
simple=false, circle=false, no coords=false,%
389
.unknown/.code={%
390
\let\keyname=\pgfkeyscurrentname%
391
\let\keyvalue=\pgfkeyscurrentvalue%
392
\ifthenelse{\equal{\keyname}{above}\OR%
393
\equal{\keyname}{left}\OR%
394
\equal{\keyname}{below}\OR%
395
\equal{\keyname}{right}\OR%
396
\equal{\keyname}{above left}\OR%
397
\equal{\keyname}{above right}\OR%
398
\equal{\keyname}{below left}\OR%
399
\equal{\keyname}{below right}}{%
400
\IfSubStr{\keyvalue}{ of }{%
401
\pgfkeys{/tikzuml/class/.cd, no coords}%
402
}{}%
403
}{}%
404
\ifx\keyvalue\pgfkeysnovalue%
405
\pgfkeys{/tikzuml/class/.cd, style/.append style/.expand once={\keyname}}%
406
\else%
407
\pgfkeys{/tikzuml/class/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
408
\fi%
409
%\errmessage{TIKZUML ERROR : in umlclass, invalid option \keyname}%
410
}%
411
}%
412
\pgfkeys{/tikzuml/class/.cd,#1}%
413
%
414
\iftikzumlclassSimpleStyle%
415
\iftikzumlclassCircleShape%
416
\pgfkeys{/tikzuml/class/.cd, width/.initial=\tikzumlSimpleInterfaceDefaultWidth}%
417
\fi%
418
\fi%
419
%
420
\pgfkeys{/tikzuml/class/.cd, x/.get=\tikzumlClassX, y/.get=\tikzumlClassY, width/.get=\tikzumlClassMinimumWidth,%
421
type/.get=\tikzumlClassTypeTmp, tags/.get=\tikzumlClassTagsTmp, template/.get=\tikzumlClassTemplateFillColorParam,%
422
name/.get=\tikzumlClassName,%
423
draw/.get=\tikzumlClassDrawColor, fill/.get=\tikzumlClassFillColor,%
424
text/.get=\tikzumlClassTextColor, fill template/.get=\tikzumlClassTemplateFillColor%
425
}%
426
%
427
\ifthenelse{\equal{\tikzumlClassTypeTmp}{class}\OR\equal{\tikzumlClassTypeTmp}{abstract}}{%
428
\def\tikzumlClassType{}%
429
}{%
430
\expandafter\def\expandafter\tikzumlClassType\expandafter{$\ll$\tikzumlClassTypeTmp$\gg$ \\}%
431
}%
432
%
433
\ifthenelse{\equal{\tikzumlClassTagsTmp}{}}{%
434
\def\tikzumlClassTags{}%
435
}{%
436
\def\tikzumlClassTags{\\ \{\tikzumlClassTagsTmp\}}%
437
}%
438
%
439
\ifthenelse{\equal{\tikzumlClassTemplateFillColorParam}{}}{%
440
\def\tikzumlClassVPadding{}%
441
\def\tikzumlClassHPadding{}%
442
}{%
443
\def\tikzumlClassVPadding{\vspace{0.1em} \\}%
444
\def\tikzumlClassHPadding{\hspace{0.5ex} $ $}%
445
}%
446
%
447
\def\tikzumlClassName{#2}%
448
%
449
\begingroup%
450
\def\_{_}\edef\x{\endgroup%
451
\def\noexpand\tikzumlClassNodeName{\tikzumlClassName}}\x%
452
%
453
\ifthenelse{\equal{\tikzumlClassName}{tikzumlEmpty}}{}{%
454
\def\tikzumlClassNodeName{\tikzumlClassName}%
455
}%
456
%
457
\StrSubstitute{\tikzumlClassNodeName}{:}{@COLON@}[\tikzumlClassNodeName]%
458
\StrSubstitute{\tikzumlClassNodeName}{\_}{@UNDERSCORE@}[\tikzumlClassNodeName]%
459
%
460
\ifthenelse{\equal{\tikzumlClassTypeTmp}{abstract}}{%
461
\let\tikzumlClassNameOld\tikzumlClassName%
462
\def\tikzumlClassName{{\it \tikzumlClassNameOld}}%
463
}{}%
464
%
465
\def\tikzumlClassPos{\tikzumlClassX,\tikzumlClassY}%
466
\def\tikzumlClassAttributes{#3}%
467
\def\tikzumlClassOperations{#4}%
468
%
469
\iftikzumlclassSimpleStyle%
470
\iftikzumlclassWithoutCoords%
471
\iftikzumlclassCircleShape%
472
\node[tikzuml simpleinterface style, draw=\tikzumlClassDrawColor, fill=\tikzumlClassFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlClassMinimumWidth, /tikzuml/class/style] (\tikzumlClassNodeName) {};%
473
\node[anchor=south] (\tikzumlClassNodeName-label) at (\tikzumlClassNodeName.north) {\begin{tabular}{c}\tikzumlClassVPadding \tikzumlClassType \tikzumlClassHPadding \textbf{\tikzumlClassName} \tikzumlClassHPadding \tikzumlClassTags \end{tabular}%
474
};%
475
\else%
476
\node[tikzuml simpleclass style, draw=\tikzumlClassDrawColor, fill=\tikzumlClassFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlClassMinimumWidth, /tikzuml/class/style] (\tikzumlClassNodeName) {\begin{tabular}{c}\tikzumlClassVPadding \tikzumlClassType \tikzumlClassHPadding \textbf{\tikzumlClassName} \tikzumlClassHPadding \tikzumlClassTags \end{tabular}%
477
};%
478
\fi%
479
\else%
480
\iftikzumlclassCircleShape%
481
\node[tikzuml simpleinterface style, draw=\tikzumlClassDrawColor, fill=\tikzumlClassFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlClassMinimumWidth, /tikzuml/class/style] (\tikzumlClassNodeName) at (\tikzumlClassPos) {};
482
\node[anchor=south] (\tikzumlClassNodeName-label) at (\tikzumlClassNodeName.north){\begin{tabular}{c}\tikzumlClassVPadding \tikzumlClassType \tikzumlClassHPadding \textbf{\tikzumlClassName} \tikzumlClassHPadding \tikzumlClassTags \end{tabular}%
483
};%
484
\else%
485
\node[tikzuml simpleclass style, draw=\tikzumlClassDrawColor, fill=\tikzumlClassFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlClassMinimumWidth, /tikzuml/class/style] (\tikzumlClassNodeName) at (\tikzumlClassPos) {\begin{tabular}{c}\tikzumlClassVPadding \tikzumlClassType \tikzumlClassHPadding \textbf{\tikzumlClassName} \tikzumlClassHPadding \tikzumlClassTags \end{tabular}%
486
};%
487
\fi%
488
\fi%
489
\else%
490
\iftikzumlclassWithoutCoords%
491
\node[tikzuml class style, draw=\tikzumlClassDrawColor, fill=\tikzumlClassFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlClassMinimumWidth, /tikzuml/class/style] (\tikzumlClassNodeName) {\begin{tabular}{c}\tikzumlClassVPadding \tikzumlClassType \tikzumlClassHPadding \textbf{\tikzumlClassName} \tikzumlClassHPadding \tikzumlClassTags \end{tabular}%
492
\nodepart{second}%
493
\begin{tabular}{l}%
494
\tikzumlClassAttributes%
495
\end{tabular}%
496
\nodepart{third}%
497
\begin{tabular}{l}%
498
\tikzumlClassOperations%
499
\end{tabular}%
500
};%
501
\else%
502
\node[tikzuml class style, draw=\tikzumlClassDrawColor, fill=\tikzumlClassFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlClassMinimumWidth, /tikzuml/class/style] (\tikzumlClassNodeName) at (\tikzumlClassPos) {\begin{tabular}{c}\tikzumlClassVPadding \tikzumlClassType \tikzumlClassHPadding \textbf{\tikzumlClassName} \tikzumlClassHPadding \tikzumlClassTags \end{tabular}%
503
\nodepart{second}%
504
\begin{tabular}{l}%
505
\tikzumlClassAttributes%
506
\end{tabular}%
507
\nodepart{third}%
508
\begin{tabular}{l}%
509
\tikzumlClassOperations%
510
\end{tabular}%
511
};%
512
\fi%
513
\fi%
514
%
515
\ifthenelse{\equal{\tikzumlClassTemplateFillColorParam}{}}{}{%
516
\draw (\tikzumlClassNodeName.north east) node[tikzuml template style, name=\tikzumlClassNodeName-template, draw=\tikzumlClassDrawColor, fill=\tikzumlClassTemplateFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont] {\tikzumlClassTemplateFillColorParam};%
517
}%
518
%
519
% add to fit
520
\ifnum\c@tikzumlPackageLevel>0%
521
\edef\tikzumlPackageFitOld{\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname}%
522
\ifthenelse{\equal{\tikzumlClassTemplateFillColorParam}{}}{%
523
\expandafter\xdef\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname{\tikzumlPackageFitOld (\tikzumlClassNodeName)}%
524
}{%
525
\expandafter\xdef\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname{\tikzumlPackageFitOld (\tikzumlClassNodeName) (\tikzumlClassNodeName-template)}%
526
}%
527
\stepcounter{tikzumlPackageClassNum}%
528
\fi%
529
\ifnum\c@tikzumlComponentLevel>0%
530
\def\tikzumlComponentFitTmp{\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname}%
531
\ifthenelse{\equal{\tikzumlClassTemplateFillColorParam}{}}{%
532
\expandafter\xdef\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname{\tikzumlComponentFitTmp (\tikzumlClassNodeName)}%
533
}{%
534
\expandafter\xdef\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname{\tikzumlComponentFitTmp (\tikzumlClassNodeName) (\tikzumlClassNodeName-template)}%
535
}%
536
\stepcounter{tikzumlComponentSubComponentNum}%
537
\fi%
538
}%
539
%
540
% shortcuts for interface, enum and typedef environments
541
\newcommand{\umlabstract}[4][]{%
542
\pgfkeys{/tikzuml/class/.cd, .unknown/.code={%
543
\let\keyname=\pgfkeyscurrentname%
544
\let\keyvalue=\pgfkeyscurrentvalue%
545
\ifthenelse{\equal{\keyname}{type}}{%
546
\errmessage{TIKZUML ERROR : in umlabstract, forbidden option type}%
547
}{}%
548
}%
549
}%
550
\pgfkeys{/tikzuml/class/.cd, #1}%
551
\umlclass[type=abstract,#1]{#2}{#3}{#4}%
552
}%
553
\newcommand{\umlinterface}[4][]{%
554
\pgfkeys{/tikzuml/class/.cd, .unknown/.code={%
555
\let\keyname=\pgfkeyscurrentname%
556
\let\keyvalue=\pgfkeyscurrentvalue%
557
\ifthenelse{\equal{\keyname}{type}}{%
558
\errmessage{TIKZUML ERROR : in umlinterface, forbidden option type}%
559
}{}%
560
}%
561
}%
562
\pgfkeys{/tikzuml/class/.cd, #1}%
563
\umlclass[type=interface,#1]{#2}{#3}{#4}%
564
}%
565
\newcommand{\umltypedef}[4][]{%
566
\pgfkeys{/tikzuml/class/.cd, .unknown/.code={%
567
\let\keyname=\pgfkeyscurrentname%
568
\let\keyvalue=\pgfkeyscurrentvalue%
569
\ifthenelse{\equal{\keyname}{type}}{%
570
\errmessage{TIKZUML ERROR : in umltypedef, forbidden option type}%
571
}{}%
572
}%
573
}%
574
\pgfkeys{/tikzuml/class/.cd, #1}%
575
\umlclass[type=typedef,#1]{#2}{#3}{#4}%
576
}%
577
\newcommand{\umlenum}[4][]{%
578
\pgfkeys{/tikzuml/class/.cd, .unknown/.code={%
579
\let\keyname=\pgfkeyscurrentname%
580
\let\keyvalue=\pgfkeyscurrentvalue%
581
\ifthenelse{\equal{\keyname}{type}}{%
582
\errmessage{TIKZUML ERROR : in umlenum, forbidden option type}%
583
}{}%
584
}%
585
}%
586
\pgfkeys{/tikzuml/class/.cd, #1}%
587
\umlclass[type=enum,#1]{#2}{#3}{#4}
588
}%
589
%
590
% shortcut to define an empty class
591
\newcommand{\umlemptyclass}[2][]{\umlclass[#1]{#2}{}{}}%
592
\newcommand{\umlsimpleclass}[2][]{%
593
\pgfkeys{/tikzuml/class/.cd, .unknown/.code={%
594
\let\keyname=\pgfkeyscurrentname%
595
\let\keyvalue=\pgfkeyscurrentvalue%
596
\ifthenelse{\equal{\keyname}{simple}}{%
597
\errmessage{TIKZUML ERROR : in umlsimpleclass, forbidden option simple}%
598
}{}%
599
}%
600
}%
601
\pgfkeys{/tikzuml/class/.cd, #1}%
602
\umlemptyclass[simple, #1]{#2}%
603
}%
604
%
605
\newcommand{\umlsimpleinterface}[2][]{%
606
\pgfkeys{/tikzuml/class/.cd, .unknown/.code={%
607
\let\keyname=\pgfkeyscurrentname%
608
\let\keyvalue=\pgfkeyscurrentvalue%
609
\ifthenelse{\equal{\keyname}{simple}}{%
610
\errmessage{TIKZUML ERROR : in umlsimpleinterface, forbidden option simple}%
611
}{%
612
\ifthenelse{\equal{\keyname}{circle}}{%
613
\errmessage{TIKZUML ERROR : in umlsimpleinterface, forbidden option circle}%
614
}{}%
615
}%
616
}%
617
}%
618
\pgfkeys{/tikzuml/class/.cd, #1}%
619
\umlsimpleclass[circle, #1]{#2}%
620
}%
621
% underline the text for static arg
622
\newcommand{\umlstatic}[1]{\underline{#1}}%
623
\newcommand{\umlvirt}[1]{\textit{#1}}%
624
%
625
% define node for n-ary association
626
\newcommand{\umlNarynode}[2][]{%
627
\def\tikzumlNaryNodeAnchor{.north}
628
\def\tikzumlNaryNodeLabelPos{above}
629
\pgfkeys{/tikzuml/narynode/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlNaryNodeDefaultWidth, name/.initial=tikzumlEmpty,%
630
draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlClassDefaultFillColor,%
631
text/.initial=\tikzumlDefaultTextColor, style/.style={},%
632
.unknown/.code={%
633
\let\keyname=\pgfkeyscurrentname%
634
\let\keyvalue=\pgfkeyscurrentvalue%
635
\ifthenelse{\equal{\keyname}{above}}{%
636
\def\tikzumlNaryNodeAnchor{.north}%
637
\def\tikzumlNaryNodeLabelPos{above}%
638
}{%
639
\ifthenelse{\equal{\keyname}{above left}}{%
640
\def\tikzumlNaryNodeAnchor{.north west}%
641
\def\tikzumlNaryNodeLabelPos{above left}%
642
}{%
643
\ifthenelse{\equal{\keyname}{left}}{%
644
\def\tikzumlNaryNodeAnchor{.west}%
645
\def\tikzumlNaryNodeLabelPos{left}%
646
}{%
647
\ifthenelse{\equal{\keyname}{below left}}{%
648
\def\tikzumlNaryNodeAnchor{.south west}%
649
\def\tikzumlNaryNodeLabelPos{below left}%
650
}{%
651
\ifthenelse{\equal{\keyname}{below}}{%
652
\def\tikzumlNaryNodeAnchor{.south}%
653
\def\tikzumlNaryNodeLabelPos{below}%
654
}{%
655
\ifthenelse{\equal{\keyname}{below right}}{%
656
\def\tikzumlNaryNodeAnchor{.south east}%
657
\def\tikzumlNaryNodeLabelPos{below right}%
658
}{%
659
\ifthenelse{\equal{\keyname}{right}}{%
660
\def\tikzumlNaryNodeAnchor{.east}%
661
\def\tikzumlNaryNodeLabelPos{right}%
662
}{%
663
\ifthenelse{\equal{\keyname}{above right}}{%
664
\def\tikzumlNaryNodeAnchor{.north east}%
665
\def\tikzumlNaryNodeLabelPos{above right}%
666
}{%
667
\ifx\keyvalue\pgfkeysnovalue%
668
\pgfkeys{/tikzuml/narynode/.cd, style/.append style/.expand once={\keyname}}%
669
\else%
670
\pgfkeys{/tikzuml/narynode/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
671
\fi%
672
%\errmessage{TIKZUML ERROR : in umlNarynode, invalid option \keyname}%
673
}%
674
}%
675
}%
676
}%
677
}%
678
}%
679
}%
680
}%
681
}%
682
}%
683
\pgfkeys{/tikzuml/narynode/.cd,#1}%
684
\pgfkeys{/tikzuml/narynode/.cd, x/.get=\tikzumlNaryNodeX, y/.get=\tikzumlNaryNodeY, width/.get=\tikzumlNaryNodeMinimumWidth,%
685
name/.get=\tikzumlNaryNodeName,%
686
draw/.get=\tikzumlNaryNodeDrawColor, fill/.get=\tikzumlNaryNodeFillColor,%
687
text/.get=\tikzumlNaryNodeTextColor%
688
}%
689
%
690
\def\tikzumlNaryName{#2}%
691
%
692
\ifthenelse{\equal{\tikzumlNaryNodeName}{tikzumlEmpty}}{%
693
\edef\tikzumlNaryNodeName{\tikzumlNaryName}%
694
}{%
695
\edef\tikzumlNaryNodeName{\tikzumlNaryNodeName}%
696
}%
697
%
698
\begingroup%
699
\def\_{_}\edef\x{\endgroup%
700
\def\noexpand\tikzumlNaryNode@nodeName{\tikzumlNaryNodeName}}\x%
701
%
702
\StrSubstitute{\tikzumlNaryNode@nodeName}{:}{@COLON@}[\tikzumlNaryNode@nodeName]%
703
\StrSubstitute{\tikzumlNaryNode@nodeName}{\_}{@UNDERSCORE@}[\tikzumlNaryNode@nodeName]%
704
%
705
\def\tikzumlNarynodePos{\tikzumlNaryNodeX,\tikzumlNaryNodeY}%
706
%
707
\node[tikzuml narynode style, draw=\tikzumlNaryNodeDrawColor, fill=\tikzumlNaryNodeFillColor, text=\tikzumlNaryNodeTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlNaryNodeMinimumWidth, minimum height=\tikzumlNaryNodeMinimumWidth, /tikzuml/narynode/style] (\tikzumlNaryNode@nodeName) at (\tikzumlNarynodePos) {};%
708
\draw (\tikzumlNaryNode@nodeName\tikzumlNaryNodeAnchor) node[\tikzumlNaryNodeLabelPos] {\tikzumlNaryName};%
709
%
710
% add to fit
711
\ifnum\c@tikzumlPackageLevel>0%
712
\edef\tikzumlPackageFitOld{\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname}%
713
\expandafter\xdef\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname{\tikzumlPackageFitOld (\tikzumlNaryNode@nodeName)}%
714
\stepcounter{tikzumlPackageClassNum}%
715
\fi%
716
}%
717
%
718
\newdimen\tikzumlNestingSymbolSize%
719
%
720
% main command to define a relation between two classes
721
% args : src class
722
% dest class
723
% optional : geometry: geometry of the line
724
% weight: barycentric weight of the middle part when geometry is a 3-line
725
% arm1, arm2: lengths of first or last part when geometry id a 3-line
726
% arg1, arg2, arg: name of the src/dest/dest side class type attribute defined by the relation
727
% mult1, mult2, mult: multiplicity of the src/dest/dest side class type attribute defined by the relation
728
% pos1, pos2, pos: position of the src/dest/dest side class type attribute defined by the relation
729
% align1, align2, align: text justification of the src/dest/dest side class type attribute defined by the relation
730
% anchor1, anchor2: src/dest anchors on linked classes
731
% angle1, angle2, loopsize: start angle, end angle and size of the relation (only if recursive)
732
% stereo: stereotype of the relation
733
% pos stereo: position of the stereotype on the relation
734
% style: style of the relation (association, aggregation, composition, inherit, ...)
735
% name: rootname used for naming nodes of the relation
736
% recursive mode: type of recursive arrow (transition for state diagrams, or default)
737
% recursive direction start/end: when transition relation, start/end directions of the relation arrow
738
\newcommand{\umlrelation}[3][]{%
739
\pgfkeys{/tikzuml/relation/.cd, geometry/.initial=\tikzumlRelationDefaultGeometry, weight/.initial=\tikzumlRelationDefaultWeight,%
740
arm1/.initial=auto, arm2/.initial=auto,%
741
arg1/.initial={}, arg2/.initial={}, arg/.initial={},%
742
mult1/.initial={}, mult2/.initial={}, mult/.initial={},%
743
pos1/.initial=\tikzumlRelationDefaultPosO, pos2/.initial=\tikzumlRelationDefaultPosT, pos/.initial=tikzumlEmpty,%
744
align1/.initial={}, align2/.initial={}, align/.initial={},%
745
anchor1/.initial=tikzumlEmpty, anchor2/.initial=tikzumlEmpty,%
746
angle1/.initial=\tikzumlRelationDefaultAngleO, angle2/.initial=\tikzumlRelationDefaultAngleT, loopsize/.initial=\tikzumlRelationDefaultLoopSize,%
747
stereo/.initial={}, pos stereo/.initial=\tikzumlRelationDefaultPosStereo,%
748
style/.initial=->, style2/.style={}, name/.initial=relation-\thetikzumlRelationNum,%
749
recursive mode/.initial=default, recursive direction start/.initial=right,%
750
recursive direction end/.initial=bottom,%
751
.unknown/.code={%
752
\let\keyname=\pgfkeyscurrentname%
753
\let\keyvalue=\pgfkeyscurrentvalue%
754
\ifthenelse{\equal{\keyname}{with port}%
755
\OR\equal{\keyname}{interface}%
756
\OR\equal{\keyname}{padding}%
757
\OR\equal{\keyname}{width}%
758
\OR\equal{\keyname}{first arm}%
759
\OR\equal{\keyname}{second arm}%
760
\OR\equal{\keyname}{middle arm}%
761
\OR\equal{\keyname}{last arm}%
762
\OR\equal{\keyname}{distance}}{}{%
763
\ifx\keyvalue\pgfkeysnovalue%
764
\pgfkeys{/tikzuml/relation/.cd, style2/.append style/.expand once={\keyname}}%
765
\else%
766
\pgfkeys{/tikzuml/relation/.cd, style2/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
767
\fi%
768
%\errmessage{TIKZUML ERROR : in umlrelation, invalid option \keyname}%
769
}%
770
}%
771
}%
772
\pgfkeys{/tikzuml/relation/.cd,#1}%
773
\pgfkeys{/tikzuml/relation/.cd, geometry/.get=\tikzumlRelationGeometry, weight/.get=\tikzumlRelationWeight,%
774
arm1/.get=\tikzumlRelationArmO, arm2/.get=\tikzumlRelationArmT,%
775
arg1/.get=\tikzumlRelationAttrName, arg2/.get=\tikzumlRelationAttrNameTO, arg/.get=\tikzumlRelationAttrNameTT,%
776
mult1/.get=\tikzumlRelationMultiplicity, mult2/.get=\tikzumlRelationMultiplicityTO, mult/.get=\tikzumlRelationMultiplicityTT,%
777
pos1/.get=\tikzumlRelationPosition, pos2/.get=\tikzumlRelationPositionTO, pos/.get=\tikzumlRelationPositionTT,%
778
align1/.get=\tikzumlRelationAlign, align2/.get=\tikzumlRelationAlignTO, align/.get=\tikzumlRelationAlignTT,%
779
anchor1/.get=\tikzumlRelationSrcAnchor, anchor2/.get=\tikzumlRelationDestAnchor,%
780
angle1/.get=\tikzumlRelationStartAngle, angle2/.get=\tikzumlRelationEndAngle, loopsize/.get=\tikzumlRelationLoopSize,%
781
stereo/.get=\tikzumlRelationStereoType, pos stereo/.get=\tikzumlRelationPositionStereotype,%
782
style/.get=\tikzumlRelationStyle, name/.get=\tikzumlRelationName,%
783
recursive mode/.get=\tikzumlRelationRecursiveMode,%
784
recursive direction start/.get=\tikzumlRelationRecursiveDirectionStart,%
785
recursive direction end/.get=\tikzumlRelationRecursiveDirectionEnd%
786
}%
787
%
788
\def\tikzumlSrcClassName{#2}%
789
%
790
% managing \_ in class names for node names
791
\begingroup%
792
\def\_{_}\edef\x{\endgroup%
793
\def\noexpand\tikzumlSrcClassNodeName{\tikzumlSrcClassName}}\x%
794
%
795
\StrSubstitute{\tikzumlSrcClassNodeName}{:}{@COLON@}[\tikzumlSrcClassNodeName]%
796
\StrSubstitute{\tikzumlSrcClassNodeName}{\_}{@UNDERSCORE@}[\tikzumlSrcClassNodeName]%
797
%
798
\def\tikzumlDestClassName{#3}%
799
\begingroup%
800
\def\_{_}\edef\x{\endgroup%
801
\def\noexpand\tikzumlDestClassNodeName{\tikzumlDestClassName}}\x%
802
%
803
\StrSubstitute{\tikzumlDestClassNodeName}{:}{@COLON@}[\tikzumlDestClassNodeName]%
804
\StrSubstitute{\tikzumlDestClassNodeName}{\_}{@UNDERSCORE@}[\tikzumlDestClassNodeName]%
805
%
806
% managing alias keys
807
\def\tikzumlRelationAttrNameT{\tikzumlRelationAttrNameTO\tikzumlRelationAttrNameTT}%
808
\def\tikzumlRelationMultiplicityT{\tikzumlRelationMultiplicityTO\tikzumlRelationMultiplicityTT}%
809
\def\tikzumlRelationAlignT{\tikzumlRelationAlignTO\tikzumlRelationAlignTT}%
810
\def\posAttrName{}%
811
\def\posMultiplicity{}%
812
\def\posAttrNameT{}%
813
\def\posMultiplicityT{}%
814
%
815
\ifthenelse{\equal{\tikzumlRelationPositionTT}{tikzumlEmpty}}{%
816
\def\tikzumlRelationPositionT{\tikzumlRelationPositionTO}%
817
}{%
818
\def\tikzumlRelationPositionT{\tikzumlRelationPositionTT}%
819
}%
820
%
821
\def\attrAlign{}%
822
\def\multAlign{}%
823
\def\attrAlignT{}%
824
\def\multAlignT{}%
825
%
826
\ifthenelse{\equal{\tikzumlRelationAlign}{left}}{%
827
\def\attrAlign{above right}%
828
\def\multAlign{below right}%
829
}{%
830
\ifthenelse{\equal{\tikzumlRelationAlign}{right}}{%
831
\def\attrAlign{above left}%
832
\def\multAlign{below left}%
833
}{}%
834
}%
835
%
836
\ifthenelse{\equal{\tikzumlRelationAlignT}{left}}{%
837
\def\attrAlignT{above right}%
838
\def\multAlignT{below right}%
839
}{%
840
\ifthenelse{\equal{\tikzumlRelationAlignT}{right}}{%
841
\def\attrAlignT{above left}%
842
\def\multAlignT{below left}%
843
}{}%
844
}%
845
%
846
% def stereotype
847
\ifthenelse{\equal{\tikzumlRelationStereoType}{}}{%
848
\def\stereotype{}%
849
}{%
850
\def\stereotype{$\ll$\tikzumlRelationStereoType$\gg$}%
851
}%
852
853
% def anchors macros
854
\ifthenelse{\equal{\tikzumlRelationSrcAnchor}{tikzumlEmpty}}{%
855
\def\tikzumlRelationSrcAnchor{}%
856
}{%
857
\let\tikzumlRelationSrcAnchorold\tikzumlRelationSrcAnchor%
858
\def\tikzumlRelationSrcAnchor{.\tikzumlRelationSrcAnchorold}%
859
}%
860
%
861
\ifthenelse{\equal{\tikzumlRelationDestAnchor}{tikzumlEmpty}}{%
862
\def\tikzumlRelationDestAnchor{}%
863
}{%
864
\let\tikzumlRelationDestAnchorold\tikzumlRelationDestAnchor%
865
\def\tikzumlRelationDestAnchor{.\tikzumlRelationDestAnchorold}%
866
}%
867
%
868
\setcounter{pos}{100*\real{\tikzumlRelationPosition}}%
869
\setcounter{posT}{100*\real{\tikzumlRelationPositionT}}%
870
\setcounter{posStereo}{100*\real{\tikzumlRelationPositionStereotype}}%
871
%
872
\pgfmathsetmacro{\tikzumlRelationWeightT}{1.0-\tikzumlRelationWeight}%
873
%
874
%\newcounter{tikzumlControlNodesNum}%
875
%\setcounter{tikzumlControlNodesNum}{0}%
876
%
877
\node[inner sep=0] (\tikzumlRelationName-middle) at (barycentric cs:\tikzumlSrcClassNodeName=\tikzumlRelationWeightT,\tikzumlDestClassNodeName=\tikzumlRelationWeight) {};%
878
%
879
% straight line
880
\ifthenelse{\equal{\tikzumlRelationGeometry}{--}}%
881
{%
882
\ifthenelse{\equal{\tikzumlSrcClassNodeName}{\tikzumlDestClassNodeName}}{%
883
\def\arcNum{1}%
884
\def\arcNumT{1}%
885
%
886
\ifthenelse{\equal{\tikzumlRelationRecursiveMode}{default}}{%
887
\xdef\tikzumlLastArc{node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
888
node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity}%
889
node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
890
node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT}%
891
node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
892
\xdef\tikzumlPath{(\tikzumlSrcClassNodeName) edge[in=\tikzumlRelationEndAngle, out=\tikzumlRelationStartAngle, distance=\tikzumlRelationLoopSize] \tikzumlLastArc%
893
node[midway, inner sep=0, name=\tikzumlRelationName-1, anchor=center] {} (\tikzumlDestClassNodeName) }%
894
}{%
895
\ifthenelse{\equal{\tikzumlRelationRecursiveMode}{transition}}{%
896
\xdef\tikzumlFirstArc{node[midway, inner sep=0, name=\tikzumlRelationName-1, anchor=center] {}}%
897
\xdef\tikzumlMidOneArc{node[midway, inner sep=0, name=\tikzumlRelationName-3, anchor=center] {}}%
898
%
899
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{\tikzumlRelationRecursiveDirectionEnd}}{%
900
\def\numArcs{3}%
901
\xdef\tikzumlLastArc{node[midway, inner sep=0, name=\tikzumlRelationName-5, anchor=center] {}}%
902
%
903
\begin{pgfonlayer}{connections}%
904
\draw (\tikzumlSrcClassNodeName) edge[in=\tikzumlRelationEndAngle, out=\tikzumlRelationStartAngle, distance=\tikzumlRelationLoopSize, draw=none] %
905
node[midway, inner sep=0, name=\tikzumlRelationName-tmp, anchor=center] {} (\tikzumlDestClassNodeName);%
906
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{right}\OR\equal{\tikzumlRelationRecursiveDirectionStart}{left}}{%
907
\node[inner sep=0, name=\tikzumlRelationName-2] at (\tikzumlSrcClassNodeName.\tikzumlRelationStartAngle -| \tikzumlRelationName-tmp) {};%
908
\node[inner sep=0, name=\tikzumlRelationName-4] at (\tikzumlDestClassNodeName.\tikzumlRelationEndAngle -| \tikzumlRelationName-tmp) {};%
909
}{%
910
\node[inner sep=0, name=\tikzumlRelationName-2] at (\tikzumlSrcClassNodeName.\tikzumlRelationStartAngle |- \tikzumlRelationName-tmp) {};%
911
\node[inner sep=0, name=\tikzumlRelationName-4] at (\tikzumlDestClassNodeName.\tikzumlRelationEndAngle |- \tikzumlRelationName-tmp) {};%
912
}%
913
\end{pgfonlayer}%
914
}{%
915
\def\numArcs{4}%
916
\xdef\tikzumlMidTwoArc{node[midway, inner sep=0, name=\tikzumlRelationName-5, anchor=center] {}}%
917
\xdef\tikzumlLastArc{node[midway, inner sep=0, name=\tikzumlRelationName-7, anchor=center] {}}%
918
%
919
\begin{pgfonlayer}{connections}%
920
\draw (\tikzumlSrcClassNodeName) edge[in=\tikzumlRelationEndAngle, out=\tikzumlRelationStartAngle, distance=\tikzumlRelationLoopSize, draw=none] %
921
node[midway, name=\tikzumlRelationName-4, anchor=center] {} (\tikzumlDestClassNodeName);%
922
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{right}\OR\equal{\tikzumlRelationRecursiveDirectionStart}{left}}{%
923
\node[inner sep=0, name=\tikzumlRelationName-2] at (\tikzumlSrcClassNodeName.\tikzumlRelationStartAngle -| \tikzumlRelationName-4) {};%
924
\node[inner sep=0, name=\tikzumlRelationName-6] at (\tikzumlDestClassNodeName.\tikzumlRelationEndAngle |- \tikzumlRelationName-4) {};%
925
}{%
926
\node[inner sep=0, name=\tikzumlRelationName-2] at (\tikzumlSrcClassNodeName.\tikzumlRelationStartAngle |- \tikzumlRelationName-4) {};%
927
\node[inner sep=0, name=\tikzumlRelationName-6] at (\tikzumlDestClassNodeName.\tikzumlRelationEndAngle -| \tikzumlRelationName-4) {};%
928
}%
929
\end{pgfonlayer}%
930
}%
931
%
932
\ifnum\numArcs=4%
933
\ifnum\theposStereo>300%
934
\pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-300)/100}%
935
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype}}%
936
\else%
937
\ifnum\theposStereo<100%
938
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype}}%
939
\else%
940
\ifnum\theposStereo>200%
941
\pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-200)/100}%
942
\xdef\tikzumlMidTwoArc{\tikzumlMidTwoArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype}}%
943
\else%
944
\pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-100)/100}%
945
\xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype}}%
946
\fi%
947
\fi%
948
\fi%
949
%
950
\ifthenelse{\thepos=300\OR\thepos=100}{%
951
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{right}}{%
952
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{bottom}}{%
953
\def\posAttrName{above right}%
954
\def\posMultiplicity{below left}%
955
}{%
956
\def\posAttrName{above left}%
957
\def\posMultiplicity{below right}%
958
}%
959
}{%
960
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{left}}{%
961
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{bottom}}{%
962
\def\posAttrName{above left}%
963
\def\posMultiplicity{below right}%
964
}{%
965
\def\posAttrName{above right}%
966
\def\posMultiplicity{below left}%
967
}%
968
}{%
969
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{top}}{%
970
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{left}}{%
971
\def\posAttrName{above right}%
972
\def\posMultiplicity{below left}%
973
}{%
974
\def\posAttrName{above left}%
975
\def\posMultiplicity{below right}%
976
}%
977
}{%
978
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{left}}{%
979
\def\posAttrName{above left}%
980
\def\posMultiplicity{below right}%
981
}{%
982
\def\posAttrName{above right}%
983
\def\posMultiplicity{below left}%
984
}%
985
}%
986
}%
987
}%
988
}{}%
989
%
990
\ifthenelse{\thepos=200}{%
991
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{right}}{%
992
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{bottom}}{%
993
\def\posAttrName{above left}%
994
\def\posMultiplicity{below right}%
995
}{%
996
\def\posAttrName{above right}%
997
\def\posMultiplicity{below left}%
998
}%
999
}{%
1000
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{left}}{%
1001
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{bottom}}{%
1002
\def\posAttrName{above right}%
1003
\def\posMultiplicity{below left}%
1004
}{%
1005
\def\posAttrName{above left}%
1006
\def\posMultiplicity{below right}%
1007
}%
1008
}{%
1009
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{top}}{%
1010
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{left}}{%
1011
\def\posAttrName{above left}%
1012
\def\posMultiplicity{below right}%
1013
}{%
1014
\def\posAttrName{above right}%
1015
\def\posMultiplicity{below left}%
1016
}%
1017
}{%
1018
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{left}}{%
1019
\def\posAttrName{above right}%
1020
\def\posMultiplicity{below left}%
1021
}{%
1022
\def\posAttrName{above left}%
1023
\def\posMultiplicity{below right}%
1024
}%
1025
}%
1026
}%
1027
}%
1028
}{}%
1029
%
1030
\ifnum\thepos>300%
1031
\pgfmathsetmacro{\tikzumlRelationPosition}{(\thepos-300)/100}%
1032
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
1033
node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity}%
1034
}%
1035
\else%
1036
\ifnum\thepos<100%
1037
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
1038
node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity}%
1039
}%
1040
\else%
1041
\ifnum\thepos>200%
1042
\pgfmathsetmacro{\tikzumlRelationPosition}{(\thepos-200)/100}%
1043
\xdef\tikzumlMidTwoArc{\tikzumlMidTwoArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
1044
node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity}%
1045
}%
1046
\else%
1047
\pgfmathsetmacro{\tikzumlRelationPosition}{(\thepos-100)/100}%
1048
\xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
1049
node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity}%
1050
}%
1051
\fi%
1052
\fi%
1053
\fi%
1054
%
1055
\ifthenelse{\theposT=300\OR\theposT=100}{%
1056
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{right}}{%
1057
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{bottom}}{%
1058
\def\posAttrNameT{above right}%
1059
\def\posMultiplicityT{below left}%
1060
}{%
1061
\def\posAttrNameT{above left}%
1062
\def\posMultiplicityT{below right}%
1063
}%
1064
}{%
1065
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{left}}{%
1066
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{bottom}}{%
1067
\def\posAttrNameT{above left}%
1068
\def\posMultiplicityT{below right}%
1069
}{%
1070
\def\posAttrNameT{above right}%
1071
\def\posMultiplicityT{below left}%
1072
}%
1073
}{%
1074
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{top}}{%
1075
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{left}}{%
1076
\def\posAttrNameT{above right}%
1077
\def\posMultiplicityT{below left}%
1078
}{%
1079
\def\posAttrNameT{above left}%
1080
\def\posMultiplicityT{below right}%
1081
}%
1082
}{%
1083
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{left}}{%
1084
\def\posAttrNameT{above left}%
1085
\def\posMultiplicityT{below right}%
1086
}{%
1087
\def\posAttrNameT{above right}%
1088
\def\posMultiplicityT{below left}%
1089
}%
1090
}%
1091
}%
1092
}%
1093
}{}%
1094
\ifthenelse{\theposT=200}{%
1095
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{right}}{%
1096
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{bottom}}{%
1097
\def\posAttrNameT{above left}%
1098
\def\posMultiplicity{below right}%
1099
}{%
1100
\def\posAttrNameT{above right}%
1101
\def\posMultiplicityT{below left}%
1102
}%
1103
}{%
1104
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{left}}{%
1105
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{bottom}}{%
1106
\def\posAttrNameT{above right}%
1107
\def\posMultiplicityT{below left}%
1108
}{%
1109
\def\posAttrNameT{above left}%
1110
\def\posMultiplicityT{below right}%
1111
}%
1112
}{%
1113
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{top}}{%
1114
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{left}}{%
1115
\def\posAttrNameT{above left}%
1116
\def\posMultiplicityT{below right}%
1117
}{%
1118
\def\posAttrNameT{above right}%
1119
\def\posMultiplicityT{below left}%
1120
}%
1121
}{%
1122
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{left}}{%
1123
\def\posAttrNameT{above right}%
1124
\def\posMultiplicityT{below left}%
1125
}{%
1126
\def\posAttrNameT{above left}%
1127
\def\posMultiplicityT{below right}%
1128
}%
1129
}%
1130
}%
1131
}%
1132
}{}%
1133
%
1134
\ifnum\theposT>300%
1135
\pgfmathsetmacro{\tikzumlRelationPositionT}{(\theposT-300)/100}%
1136
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
1137
node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT}%
1138
}%
1139
\else%
1140
\ifnum\theposT<100%
1141
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
1142
node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT}%
1143
}%
1144
\else%
1145
\ifnum\theposT>200%
1146
\pgfmathsetmacro{\tikzumlRelationPositionT}{(\theposT-200)/100}%
1147
\xdef\tikzumlMidTwoArc{\tikzumlMidTwoArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
1148
node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT}%
1149
}%
1150
\else%
1151
\pgfmathsetmacro{\tikzumlRelationPositionT}{(\theposT-100)/100}%
1152
\xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
1153
node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT}%
1154
}%
1155
\fi%
1156
\fi%
1157
\fi%
1158
\else%
1159
\ifnum\theposStereo>200%
1160
\pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-200)/100}%
1161
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
1162
\else%
1163
\ifnum\theposStereo<100%
1164
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
1165
\else%
1166
\pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-100)/100}%
1167
\xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
1168
\fi%
1169
\fi%
1170
%
1171
\ifthenelse{\thepos=100}{%
1172
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{right}}{%
1173
\ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
1174
\def\posAttrName{above right}%
1175
\def\posMultiplicity{below left}%
1176
}{%
1177
\def\posAttrName{above left}%
1178
\def\posMultiplicity{below right}%
1179
}%
1180
}{%
1181
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{left}}{%
1182
\ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
1183
\def\posAttrName{above left}%
1184
\def\posMultiplicity{below right}%
1185
}{%
1186
\def\posAttrName{above right}%
1187
\def\posMultiplicity{below left}%
1188
}%
1189
}{%
1190
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{top}}{%
1191
\ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
1192
\def\posAttrName{above right}%
1193
\def\posMultiplicity{below left}%
1194
}{%
1195
\def\posAttrName{above left}%
1196
\def\posMultiplicity{below right}%
1197
}%
1198
}{%
1199
\ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
1200
\def\posAttrName{above left}%
1201
\def\posMultiplicity{below right}%
1202
}{%
1203
\def\posAttrName{above right}%
1204
\def\posMultiplicity{below left}%
1205
}%
1206
}%
1207
}%
1208
}%
1209
}{}%
1210
%
1211
\ifthenelse{\thepos=200}{%
1212
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{right}}{%
1213
\ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
1214
\def\posAttrName{above left}%
1215
\def\posMultiplicity{below right}%
1216
}{%
1217
\def\posAttrName{above right}%
1218
\def\posMultiplicity{below left}%
1219
}%
1220
}{%
1221
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{left}}{%
1222
\ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
1223
\def\posAttrName{above right}%
1224
\def\posMultiplicity{below left}%
1225
}{%
1226
\def\posAttrName{above left}%
1227
\def\posMultiplicity{below right}%
1228
}%
1229
}{%
1230
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{top}}{%
1231
\ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
1232
\def\posAttrName{above left}%
1233
\def\posMultiplicity{below right}%
1234
}{%
1235
\def\posAttrName{above right}%
1236
\def\posMultiplicity{below left}%
1237
}%
1238
}{%
1239
\ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
1240
\def\posAttrName{above right}%
1241
\def\posMultiplicity{below left}%
1242
}{%
1243
\def\posAttrName{above left}%
1244
\def\posMultiplicity{below right}%
1245
}%
1246
}%
1247
}%
1248
}%
1249
}{}%
1250
%
1251
\ifnum\thepos>200%
1252
\pgfmathsetmacro{\tikzumlRelationPosition}{(\thepos-200)/100}%
1253
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
1254
node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity}%
1255
}%
1256
\else%
1257
\ifnum\thepos<100%
1258
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
1259
node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity}%
1260
}%
1261
\else%
1262
\pgfmathsetmacro{\tikzumlRelationPosition}{(\thepos-100)/100}%
1263
\xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
1264
node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity}%
1265
}%
1266
\fi%
1267
\fi%
1268
%
1269
\ifthenelse{\theposT=100}{%
1270
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{right}}{%
1271
\ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
1272
\def\posAttrNameT{above right}%
1273
\def\posMultiplicityT{below left}%
1274
}{%
1275
\def\posAttrNameT{above left}%
1276
\def\posMultiplicityT{below right}%
1277
}%
1278
}{%
1279
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{left}}{%
1280
\ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
1281
\def\posAttrNameT{above left}%
1282
\def\posMultiplicityT{below right}%
1283
}{%
1284
\def\posAttrNameT{above right}%
1285
\def\posMultiplicityT{below left}%
1286
}%
1287
}{%
1288
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{top}}{%
1289
\ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
1290
\def\posAttrNameT{above right}%
1291
\def\posMultiplicityT{below left}%
1292
}{%
1293
\def\posAttrNameT{above left}%
1294
\def\posMultiplicityT{below right}%
1295
}%
1296
}{%
1297
\ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
1298
\def\posAttrNameT{above left}%
1299
\def\posMultiplicityT{below right}%
1300
}{%
1301
\def\posAttrNameT{above right}%
1302
\def\posMultiplicityT{below left}%
1303
}%
1304
}%
1305
}%
1306
}%
1307
}{}%
1308
%
1309
\ifthenelse{\theposT=200}{%
1310
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{right}}{%
1311
\ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
1312
\def\posAttrNameT{above left}%
1313
\def\posMultiplicityT{below right}%
1314
}{%
1315
\def\posAttrNameT{above right}%
1316
\def\posMultiplicityT{below left}%
1317
}%
1318
}{%
1319
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{left}}{%
1320
\ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
1321
\def\posAttrNameT{above right}%
1322
\def\posMultiplicityT{below left}%
1323
}{%
1324
\def\posAttrNameT{above left}%
1325
\def\posMultiplicityT{below right}%
1326
}%
1327
}{%
1328
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{top}}{%
1329
\ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
1330
\def\posAttrNameT{above left}%
1331
\def\posMultiplicityT{below right}%
1332
}{%
1333
\def\posAttrNameT{above right}%
1334
\def\posMultiplicityT{below left}%
1335
}%
1336
}{%
1337
\ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
1338
\def\posAttrNameT{above right}%
1339
\def\posMultiplicityT{below left}%
1340
}{%
1341
\def\posAttrNameT{above left}%
1342
\def\posMultiplicityT{below right}%
1343
}%
1344
}%
1345
}%
1346
}%
1347
}{}%
1348
%
1349
\ifnum\theposT>200%
1350
\pgfmathsetmacro{\tikzumlRelationPositionT}{(\theposT-200)/100}%
1351
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
1352
node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT}%
1353
}%
1354
\else%
1355
\ifnum\theposT<100%
1356
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
1357
node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT}%
1358
}%
1359
\else%
1360
\pgfmathsetmacro{\tikzumlRelationPositionT}{(\theposT-100)/100}%
1361
\xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
1362
node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT}%
1363
}%
1364
\fi%
1365
\fi%
1366
\fi%
1367
%
1368
\ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{\tikzumlRelationRecursiveDirectionEnd}}{%
1369
\xdef\tikzumlPath{(\tikzumlSrcClassNodeName.\tikzumlRelationStartAngle) -- \tikzumlFirstArc (\tikzumlRelationName-2.center) -- \tikzumlMidOneArc (\tikzumlRelationName-4.center) -- \tikzumlLastArc (\tikzumlDestClassNodeName.\tikzumlRelationEndAngle) }%
1370
\ifnum\thetikzumlStateLevel>0%
1371
\def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
1372
\expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\tikzumlRelationName-1) (\tikzumlRelationName-2) (\tikzumlRelationName-3) (\tikzumlRelationName-4) (\tikzumlRelationName-5)}%
1373
\fi%
1374
}{%
1375
\xdef\tikzumlPath{(\tikzumlSrcClassNodeName.\tikzumlRelationStartAngle) -- \tikzumlFirstArc (\tikzumlRelationName-2.center) -- \tikzumlMidOneArc (\tikzumlRelationName-4.center) -- \tikzumlMidTwoArc (\tikzumlRelationName-6.center) -- \tikzumlLastArc (\tikzumlDestClassNodeName.\tikzumlRelationEndAngle) }%
1376
\ifnum\thetikzumlStateLevel>0%
1377
\def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
1378
\expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\tikzumlRelationName-1) (\tikzumlRelationName-2) (\tikzumlRelationName-3) (\tikzumlRelationName-4) (\tikzumlRelationName-5) (\tikzumlRelationName-6) (\tikzumlRelationName-7)}%
1379
\fi%
1380
}%
1381
}{}%
1382
}%
1383
}{%
1384
\def\arcNum{1}%
1385
\def\arcNumT{1}%
1386
%
1387
\node[inner sep=0] (\tikzumlRelationName-1) at (\tikzumlRelationName-middle) {};%
1388
\xdef\tikzumlLastArc{node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
1389
node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity}%
1390
node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
1391
node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT}%
1392
node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
1393
\xdef\tikzumlPath{(\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor) -- \tikzumlLastArc (\tikzumlDestClassNodeName\tikzumlRelationDestAnchor) }%
1394
\ifnum\thetikzumlStateLevel>0%
1395
\def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
1396
\expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\tikzumlRelationName-1) }%
1397
\fi%
1398
}%
1399
}{%
1400
% first vertical then horizontal line
1401
\ifthenelse{\equal{\tikzumlRelationGeometry}{|-}}%
1402
{%
1403
%\setcounter{tikzumlControlNodesNum}{1}%
1404
%
1405
\def\tikzumlFirstArc{node[midway, inner sep=0, name=\tikzumlRelationName-1, anchor=center] {} }%
1406
\def\tikzumlLastArc{node[midway, inner sep=0, name=\tikzumlRelationName-3, anchor=center]{} }%
1407
%
1408
\begin{pgfonlayer}{connections}%
1409
\node[inner sep=0] (\tikzumlRelationName-2) at (\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor |- \tikzumlDestClassNodeName\tikzumlRelationDestAnchor) {};%
1410
\end{pgfonlayer}%
1411
%
1412
\ifnum\theposStereo>100%
1413
\pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-100)/100}%
1414
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
1415
\else%
1416
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
1417
\fi%
1418
%
1419
\ifnum\thepos>100%
1420
\pgfmathsetmacro{\tikzumlRelationPosition}{(\thepos-100)/100}%
1421
\def\arcNum{2}%
1422
\else%
1423
\def\arcNum{1}%
1424
\ifnum\thepos=100%
1425
\def\posAttrName{above left}%
1426
\def\posMultiplicity{below right}%
1427
\fi%
1428
\fi%
1429
%
1430
\ifnum\arcNum=1%
1431
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
1432
node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity} }%
1433
\fi%
1434
\ifnum\arcNum=2%
1435
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
1436
node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity} }%
1437
\fi%
1438
%
1439
\ifnum\theposT>100%
1440
\pgfmathsetmacro{\tikzumlRelationPositionT}{(\theposT-100)/100}%
1441
\def\arcNumT{2}%
1442
\else%
1443
\def\arcNumT{1}%
1444
\ifnum\theposT=100%
1445
\def\posAttrNameT{above left}%
1446
\def\posMultiplicityT{below right}%
1447
\fi%
1448
\fi%
1449
%
1450
\ifnum\arcNumT=1%
1451
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
1452
node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT} }%
1453
\fi%
1454
\ifnum\arcNumT=2%
1455
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
1456
node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT} }%
1457
\fi%
1458
%
1459
\xdef\tikzumlPath{(\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor) -- \tikzumlFirstArc (\tikzumlRelationName-2.base) -- \tikzumlLastArc (\tikzumlDestClassNodeName\tikzumlRelationDestAnchor) }%
1460
\ifnum\thetikzumlStateLevel>0%
1461
\def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
1462
\expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\tikzumlRelationName-1) (\tikzumlRelationName-2) (\tikzumlRelationName-3) }%
1463
\fi%
1464
}{%
1465
% first horizontal then vertical line
1466
\ifthenelse{\equal{\tikzumlRelationGeometry}{-|}}%
1467
{%
1468
%\setcounter{tikzumlControlNodesNum}{1}%
1469
%
1470
\def\tikzumlFirstArc{node[midway, inner sep=0, name=\tikzumlRelationName-1, anchor=center]{} }%
1471
\def\tikzumlLastArc{node[midway, inner sep=0, name=\tikzumlRelationName-3, anchor=center] {} }%
1472
%
1473
\begin{pgfonlayer}{connections}%
1474
\node[inner sep=0] (\tikzumlRelationName-2) at (\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor -| \tikzumlDestClassNodeName\tikzumlRelationDestAnchor) {};%
1475
\end{pgfonlayer}%
1476
%
1477
\ifnum\theposStereo>100%
1478
\pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-100)/100}%
1479
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
1480
\else%
1481
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
1482
\fi%
1483
%
1484
\ifnum\thepos>100%
1485
\pgfmathsetmacro{\tikzumlRelationPosition}{(\thepos-100)/100}%
1486
\def\arcNum{2}%
1487
\else%
1488
\def\arcNum{1}%
1489
\ifnum\thepos=100%
1490
\def\posAttrName{above left}%
1491
\def\posMultiplicity{below right}%
1492
\fi%
1493
\fi%
1494
%
1495
\ifnum\arcNum=1%
1496
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
1497
node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity} }%
1498
\fi%
1499
\ifnum\arcNum=2%
1500
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
1501
node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity} }%
1502
\fi%
1503
%
1504
\ifnum\theposT>100%
1505
\pgfmathsetmacro{\tikzumlRelationPositionT}{(\theposT-100)/100}%
1506
\def\arcNumT{2}%
1507
\else%
1508
\def\arcNumT{1}%
1509
\ifnum\theposT=100%
1510
\def\posAttrNameT{above left}%
1511
\def\posMultiplicityT{below right}%
1512
\fi%
1513
\fi%
1514
%
1515
\ifnum\arcNumT=1%
1516
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
1517
node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT} }%
1518
\fi%
1519
\ifnum\arcNumT=2%
1520
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
1521
node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT} }%
1522
\fi%
1523
%
1524
\xdef\tikzumlPath{(\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor) -- \tikzumlFirstArc (\tikzumlRelationName-2.base) -- \tikzumlLastArc (\tikzumlDestClassNodeName\tikzumlRelationDestAnchor) }%
1525
\ifnum\thetikzumlStateLevel>0%
1526
\def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
1527
\expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\tikzumlRelationName-1) (\tikzumlRelationName-2) (\tikzumlRelationName-3) }%
1528
\fi%
1529
}{%
1530
% first vertical, then horizontal, finally vertical line
1531
\ifthenelse{\equal{\tikzumlRelationGeometry}{|-|}}%
1532
{%
1533
%\setcounter{tikzumlControlNodesNum}{2}%
1534
%
1535
\def\tikzumlFirstArc{node[midway, inner sep=0, name=\tikzumlRelationName-1, anchor=center] {} }%
1536
\def\tikzumlLastArc{node[midway, inner sep=0, name=\tikzumlRelationName-5, anchor=center] {} }%
1537
\def\tikzumlMidOneArc{ }%
1538
%
1539
\begin{pgfonlayer}{connections}%
1540
%
1541
\ifthenelse{\equal{\tikzumlRelationArmO}{auto}}{%
1542
\ifthenelse{\equal{\tikzumlRelationArmT}{auto}}{%
1543
\node[inner sep=0] (\tikzumlRelationName-3) at (\tikzumlRelationName-middle) {};%
1544
\node[inner sep=0] (\tikzumlRelationName-2) at (\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor |- \tikzumlRelationName-3) {};%
1545
\node[inner sep=0] (\tikzumlRelationName-4) at (\tikzumlRelationName-3 -| \tikzumlDestClassNodeName\tikzumlRelationDestAnchor) {};%
1546
}{%
1547
\draw (\tikzumlDestClassNodeName\tikzumlRelationDestAnchor)+(0,\tikzumlRelationArmT) node[inner sep=0, name=\tikzumlRelationName-4] {};%
1548
\node[inner sep=0] (\tikzumlRelationName-2) at (\tikzumlRelationName-4 -| \tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor) {};%
1549
\node[inner sep=0] (\tikzumlRelationName-3) at (barycentric cs:\tikzumlRelationName-2=0.5,\tikzumlRelationName-4=0.5) {};%
1550
}%
1551
}{%
1552
\draw (\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor)+(0,\tikzumlRelationArmO) node[inner sep=0, name=\tikzumlRelationName-2] {};%
1553
\node[inner sep=0] (\tikzumlRelationName-4) at (\tikzumlRelationName-2 -| \tikzumlDestClassNodeName\tikzumlRelationDestAnchor) {};%
1554
\node[inner sep=0] (\tikzumlRelationName-3) at (barycentric cs:\tikzumlRelationName-2=0.5,\tikzumlRelationName-4=0.5) {};%
1555
}%
1556
\end{pgfonlayer}%
1557
%
1558
\ifnum\theposStereo>200%
1559
\pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-200)/100}%
1560
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
1561
\else%
1562
\ifnum\theposStereo<100%
1563
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
1564
\else%
1565
\pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-100)/100}%
1566
\xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
1567
\fi%
1568
\fi%
1569
%
1570
\ifthenelse{\thepos=200\OR\thepos=100}{%
1571
\def\posAttrName{above left}%
1572
\def\posMultiplicity{below right}%
1573
}{}%
1574
%
1575
\ifthenelse{\thepos>200}{%
1576
\pgfmathsetmacro{\tikzumlRelationPosition}{(\thepos-200)/100}%
1577
\def\arcNum{3}%
1578
}{%
1579
\ifthenelse{\thepos<100}{%
1580
\def\arcNum{1}%
1581
}{%
1582
\pgfmathsetmacro{\tikzumlRelationPosition}{(\thepos-100)/100}%
1583
\def\arcNum{2}%
1584
}%
1585
}%
1586
%
1587
\ifnum\arcNum=1%
1588
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
1589
node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity} }%
1590
\fi%
1591
\ifnum\arcNum=2%
1592
\xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
1593
node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity} }%
1594
\fi%
1595
\ifnum\arcNum=3%
1596
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
1597
node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity} }%
1598
\fi%
1599
%
1600
\ifthenelse{\theposT=200\OR\theposT=100}{%
1601
\def\posAttrNameT{above left}%
1602
\def\posMultiplicityT{below right}%
1603
}{}%
1604
%
1605
\ifthenelse{\theposT>200}{%
1606
\pgfmathsetmacro{\tikzumlRelationPositionT}{(\theposT-200)/100}%
1607
\def\arcNumT{3}%
1608
}{%
1609
\ifthenelse{\theposT<100}{%
1610
\def\arcNumT{1}%
1611
}{%
1612
\pgfmathsetmacro{\tikzumlRelationPositionT}{(\theposT-100)/100}%
1613
\def\arcNumT{2}%
1614
}%
1615
}%
1616
%
1617
\ifnum\arcNumT=1%
1618
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
1619
node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT} }%
1620
\fi%
1621
\ifnum\arcNumT=2%
1622
\xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
1623
node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT} }%
1624
\fi%
1625
\ifnum\arcNumT=3%
1626
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
1627
node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT} }%
1628
\fi%
1629
%
1630
\xdef\tikzumlPath{(\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor) -- \tikzumlFirstArc (\tikzumlRelationName-2.base) -- \tikzumlMidOneArc (\tikzumlRelationName-4.base) -- \tikzumlLastArc (\tikzumlDestClassNodeName\tikzumlRelationDestAnchor) }%
1631
\ifnum\thetikzumlStateLevel>0%
1632
\def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
1633
\expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\tikzumlRelationName-1) (\tikzumlRelationName-2) (\tikzumlRelationName-3) (\tikzumlRelationName-4) (\tikzumlRelationName-5) }%
1634
\fi%
1635
}{%
1636
% first horizontal, then vertical, finally horizontal line
1637
\ifthenelse{\equal{\tikzumlRelationGeometry}{-|-}}%
1638
{%
1639
%\setcounter{tikzumlControlNodesNum}{2}%
1640
%
1641
\def\tikzumlFirstArc{node[midway, inner sep=0, name=\tikzumlRelationName-1, anchor=center] {} }%
1642
\def\tikzumlLastArc{node[midway, inner sep=0, name=\tikzumlRelationName-5, anchor=center] {} }%
1643
\def\tikzumlMidOneArc{}%
1644
%
1645
\begin{pgfonlayer}{connections}%
1646
%
1647
\ifthenelse{\equal{\tikzumlRelationArmO}{auto}}{%
1648
\ifthenelse{\equal{\tikzumlRelationArmT}{auto}}{%
1649
\node[inner sep=0] (\tikzumlRelationName-3) at (\tikzumlRelationName-middle) {};%
1650
\node[inner sep=0] (\tikzumlRelationName-2) at (\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor -| \tikzumlRelationName-3) {};%
1651
\node[inner sep=0] (\tikzumlRelationName-4) at (\tikzumlRelationName-3 |- \tikzumlDestClassNodeName\tikzumlRelationDestAnchor) {};%
1652
}{%
1653
\draw (\tikzumlDestClassNodeName\tikzumlRelationDestAnchor)+(\tikzumlRelationArmT,0) node[inner sep=0, name=\tikzumlRelationName-4] {};%
1654
\node[inner sep=0] (\tikzumlRelationName-2) at (\tikzumlRelationName-4 |- \tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor) {};%
1655
\node[inner sep=0] (\tikzumlRelationName-3) at (barycentric cs:\tikzumlRelationName-2=0.5,\tikzumlRelationName-4=0.5) {};%
1656
}%
1657
}{%
1658
\draw (\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor)+(\tikzumlRelationArmO,0) node[inner sep=0, name=\tikzumlRelationName-2] {};%
1659
\node[inner sep=0] (\tikzumlRelationName-4) at (\tikzumlRelationName-2 |- \tikzumlDestClassNodeName\tikzumlRelationDestAnchor) {};%
1660
\node[inner sep=0] (\tikzumlRelationName-3) at (barycentric cs:\tikzumlRelationName-2=0.5,\tikzumlRelationName-4=0.5) {};%
1661
}%
1662
\end{pgfonlayer}%
1663
%
1664
\ifnum\theposStereo>200%
1665
\pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-200)/100}%
1666
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
1667
\else%
1668
\ifnum\theposStereo<100%
1669
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
1670
\else%
1671
\pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-100)/100}%
1672
\xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
1673
\fi%
1674
\fi%
1675
%
1676
\ifthenelse{\thepos=200\OR\thepos=100}{%
1677
\def\posAttrName{above left}%
1678
\def\posMultiplicity{below right}%
1679
}{}%
1680
%
1681
\ifthenelse{\thepos>200}{%
1682
\pgfmathsetmacro{\tikzumlRelationPosition}{(\thepos-200)/100}%
1683
\def\arcNum{3}%
1684
}{%
1685
\ifthenelse{\thepos<100}{%
1686
\def\arcNum{1}%
1687
}{%
1688
\pgfmathsetmacro{\tikzumlRelationPosition}{(\thepos-100)/100}%
1689
\def\arcNum{2}%
1690
}%
1691
}%
1692
%
1693
\ifnum\arcNum=1%
1694
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
1695
node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity} }%
1696
\fi%
1697
\ifnum\arcNum=2%
1698
\xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
1699
node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity} }%
1700
\fi%
1701
\ifnum\arcNum=3%
1702
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
1703
node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity} }%
1704
\fi%
1705
%
1706
\ifthenelse{\theposT=200\OR\theposT=100}{%
1707
\def\posAttrNameT{above left}%
1708
\def\posMultiplicityT{below right}%
1709
}{}%
1710
%
1711
\ifthenelse{\theposT>200}{%
1712
\pgfmathsetmacro{\tikzumlRelationPositionT}{(\theposT-200)/100}%
1713
\def\arcNumT{3}%
1714
}{%
1715
\ifthenelse{\theposT<100}{%
1716
\def\arcNumT{1}%
1717
}{%
1718
\pgfmathsetmacro{\tikzumlRelationPositionT}{(\theposT-100)/100}%
1719
\def\arcNumT{2}%
1720
}%
1721
}%
1722
%
1723
\ifnum\arcNumT=1%
1724
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
1725
node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT} }%
1726
\fi%
1727
\ifnum\arcNumT=2%
1728
\xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
1729
node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT} }%
1730
\fi%
1731
\ifnum\arcNumT=3%
1732
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
1733
node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT} }%
1734
\fi%
1735
%
1736
\xdef\tikzumlPath{(\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor) -- \tikzumlFirstArc (\tikzumlRelationName-2.base) -- \tikzumlMidOneArc (\tikzumlRelationName-4.base) -- \tikzumlLastArc (\tikzumlDestClassNodeName\tikzumlRelationDestAnchor) }%
1737
\ifnum\thetikzumlStateLevel>0%
1738
\def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
1739
\expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\tikzumlRelationName-1) (\tikzumlRelationName-2) (\tikzumlRelationName-3) (\tikzumlRelationName-4) (\tikzumlRelationName-5) }%
1740
\fi%
1741
}{%
1742
\errmessage{TIKZUML ERROR : Unknown geometry value !!! It should be in the following list : --, |-, -|, |-|, -|-}%
1743
}%
1744
}%
1745
}%
1746
}%
1747
}%
1748
%
1749
\begin{pgfonlayer}{connections}%
1750
\ifthenelse{\equal{\tikzumlRelationStyle}{tikzuml nesting style}}{%
1751
\pgfarrowsdeclare{nested}{nested}{...}
1752
{
1753
\tikzumlNestingSymbolSize=0.2pt%
1754
\advance\tikzumlNestingSymbolSize by .5\pgflinewidth%
1755
\pgfsetdash{}{0pt} % do not dash
1756
\pgfsetroundjoin % fix join
1757
\pgfsetroundcap % fix cap
1758
\pgfpathmoveto{\pgfpoint{-16*\tikzumlNestingSymbolSize}{0pt}}%
1759
\pgfpatharc{180}{90}{8*\tikzumlNestingSymbolSize}%
1760
\pgfpatharc{90}{0}{8*\tikzumlNestingSymbolSize}%
1761
\pgfpatharc{0}{-90}{8*\tikzumlNestingSymbolSize}%
1762
\pgfpatharc{-90}{-180}{8*\tikzumlNestingSymbolSize}%
1763
\pgfpathmoveto{\pgfpoint{-8*\tikzumlNestingSymbolSize}{8*\tikzumlNestingSymbolSize}}%
1764
\pgfpathlineto{\pgfpoint{-8*\tikzumlNestingSymbolSize}{-8*\tikzumlNestingSymbolSize}}%
1765
\pgfusepathqstroke%
1766
}%
1767
\draw[auto, nested-, font=\tikzumlDefaultFont, \tikzumlRelationStyle, /tikzuml/relation/style2] \tikzumlPath ;%
1768
}{
1769
\draw[auto, font=\tikzumlDefaultFont, \tikzumlRelationStyle, /tikzuml/relation/style2] \tikzumlPath ;%
1770
}
1771
\end{pgfonlayer}%
1772
%
1773
\stepcounter{tikzumlRelationNum}%
1774
}%
1775
%
1776
% shortcuts of \umlrelation
1777
\newcommand{\umlHVrelation}[3][]{%
1778
\pgfkeys{/tikzuml/HVrelation/.cd,%
1779
.unknown/.code={%
1780
\let\keyname=\pgfkeyscurrentname%
1781
\let\keyvalue=\pgfkeyscurrentvalue%
1782
\ifthenelse{\equal{\keyname}{geometry}}{%
1783
\errmessage{TIKZUML ERROR : in umlHVrelation, forbidden option geometry}%
1784
}{}%
1785
}}%
1786
\pgfkeys{/tikzuml/HVrelation/.cd, #1}%
1787
\umlrelation[geometry=-|, #1]{#2}{#3}%
1788
}%
1789
%
1790
\newcommand{\umlVHrelation}[3][]{%
1791
\pgfkeys{/tikzuml/VHrelation/.cd,%
1792
.unknown/.code={%
1793
\let\keyname=\pgfkeyscurrentname%
1794
\let\keyvalue=\pgfkeyscurrentvalue%
1795
\ifthenelse{\equal{\keyname}{geometry}}{%
1796
\errmessage{TIKZUML ERROR : in umlVHrelation, forbidden option geometry}%
1797
}{}%
1798
}}%
1799
\pgfkeys{/tikzuml/VHrelation/.cd, #1}%
1800
\umlrelation[geometry=|-, #1]{#2}{#3}%
1801
}%
1802
%
1803
\newcommand{\umlHVHrelation}[3][]{%
1804
\pgfkeys{/tikzuml/HVHrelation/.cd,%
1805
.unknown/.code={%
1806
\let\keyname=\pgfkeyscurrentname%
1807
\let\keyvalue=\pgfkeyscurrentvalue%
1808
\ifthenelse{\equal{\keyname}{geometry}}{%
1809
\errmessage{TIKZUML ERROR : in umlHVHrelation, forbidden option geometry}%
1810
}{}%
1811
}}%
1812
\pgfkeys{/tikzuml/HVHrelation/.cd, #1}%
1813
\umlrelation[geometry=-|-, #1]{#2}{#3}%
1814
}%
1815
%
1816
\newcommand{\umlVHVrelation}[3][]{%
1817
\pgfkeys{/tikzuml/VHVrelation/.cd,%
1818
.unknown/.code={%
1819
\let\keyname=\pgfkeyscurrentname%
1820
\let\keyvalue=\pgfkeyscurrentvalue%
1821
\ifthenelse{\equal{\keyname}{geometry}}{%
1822
\errmessage{TIKZUML ERROR : in umlVHVrelation, forbidden option geometry}%
1823
}{}%
1824
}}%
1825
\pgfkeys{/tikzuml/VHVrelation/.cd, #1}%
1826
\umlrelation[geometry=|-|, #1]{#2}{#3}%
1827
}%
1828
%
1829
%
1830
% shortcuts for relations
1831
\newcommand{\umlinherit}[3][]{\umlrelation[style={tikzuml inherit style}, #1]{#2}{#3}}%
1832
\newcommand{\umlimpl}[3][]{\umlrelation[style={tikzuml implements style}, #1]{#2}{#3}}%
1833
\newcommand{\umlreal}[3][]{\umlrelation[style={tikzuml implements style}, #1]{#2}{#3}}%
1834
\newcommand{\umlassoc}[3][]{\umlrelation[style={tikzuml association style}, #1]{#2}{#3}}%
1835
\newcommand{\umlbiassoc}[3][]{\umlrelation[style={tikzuml bidirectional association style}, #1]{#2}{#3}}%
1836
\newcommand{\umluniassoc}[3][]{\umlrelation[style={tikzuml unidirectional association style}, #1]{#2}{#3}}%
1837
\newcommand{\umlaggreg}[3][]{\umlrelation[style={tikzuml aggregation style}, #1]{#2}{#3}}%
1838
\newcommand{\umluniaggreg}[3][]{\umlrelation[style={tikzuml unidirectional aggregation style}, #1]{#2}{#3}}%
1839
\newcommand{\umlcompo}[3][]{\umlrelation[style={tikzuml composition style}, #1]{#2}{#3}}%
1840
\newcommand{\umlunicompo}[3][]{\umlrelation[style={tikzuml unidirectional composition style}, #1]{#2}{#3}}%
1841
\newcommand{\umlimport}[3][]{\umlrelation[style={tikzuml import style}, #1]{#2}{#3}}%
1842
\newcommand{\umlnest}[3][]{\umlrelation[style={tikzuml nesting style}, #1]{#2}{#3}}%
1843
\newcommand{\umldep}[3][]{\umlrelation[style={tikzuml dependency style}, #1]{#2}{#3}}%
1844
\newcommand{\umlfriend}[3][]{%
1845
\pgfkeys{/tikzuml/friendrelation/.cd,%
1846
.unknown/.code={%
1847
\let\keyname=\pgfkeyscurrentname%
1848
\let\keyvalue=\pgfkeyscurrentvalue%
1849
\ifthenelse{\equal{\keyname}{stereo}}{%
1850
\errmessage{TIKZUML ERROR : in umlfriend, forbidden option stereo}%
1851
}{}%
1852
}}%
1853
\pgfkeys{/tikzuml/friendrelation/.cd, #1}%
1854
\umlrelation[stereo=friend, style={tikzuml dependency style}, #1]{#2}{#3}%
1855
}%
1856
%
1857
\newcommand{\umlHVinherit}[3][]{\umlHVrelation[style={tikzuml inherit style}, #1]{#2}{#3}}%
1858
\newcommand{\umlHVimpl}[3][]{\umlHVrelation[style={tikzuml implements style}, #1]{#2}{#3}}%
1859
\newcommand{\umlHVreal}[3][]{\umlHVrelation[style={tikzuml implements style}, #1]{#2}{#3}}%
1860
\newcommand{\umlHVassoc}[3][]{\umlHVrelation[style={tikzuml association style}, #1]{#2}{#3}}%
1861
\newcommand{\umlHVuniassoc}[3][]{\umlHVrelation[style={tikzuml unidirectional association style}, #1]{#2}{#3}}%
1862
\newcommand{\umlHVaggreg}[3][]{\umlHVrelation[style={tikzuml aggregation style}, #1]{#2}{#3}}%
1863
\newcommand{\umlHVuniaggreg}[3][]{\umlHVrelation[style={tikzuml unidirectional aggregation style}, #1]{#2}{#3}}%
1864
\newcommand{\umlHVcompo}[3][]{\umlHVrelation[style={tikzuml composition style}, #1]{#2}{#3}}%
1865
\newcommand{\umlHVunicompo}[3][]{\umlHVrelation[style={tikzuml unidirectional composition style}, #1]{#2}{#3}}%
1866
\newcommand{\umlHVimport}[3][]{\umlHVrelation[style={tikzuml import style}, #1]{#2}{#3}}%
1867
\newcommand{\umlHVnest}[3][]{\umlHVrelation[style={tikzuml nesting style}, #1]{#2}{#3}}%
1868
\newcommand{\umlHVdep}[3][]{\umlHVrelation[style={tikzuml dependency style}, #1]{#2}{#3}}%
1869
\newcommand{\umlHVfriend}[3][]{%
1870
\pgfkeys{/tikzuml/friendrelation/.cd,%
1871
.unknown/.code={%
1872
\let\keyname=\pgfkeyscurrentname%
1873
\let\keyvalue=\pgfkeyscurrentvalue%
1874
\ifthenelse{\equal{\keyname}{stereo}}{%
1875
\errmessage{TIKZUML ERROR : in umlHVfriend, forbidden option stereo}%
1876
}{%
1877
\ifthenelse{\equal{\keyname}{geometry}}{%
1878
\errmessage{TIKZUML ERROR : in umlHVfriend, forbidden option geometry}%
1879
}{}%
1880
}%
1881
}}%
1882
\pgfkeys{/tikzuml/friendrelation/.cd, #1}%
1883
\umlrelation[geometry=-|, stereo=friend, style={tikzuml dependency style}, #1]{#2}{#3}%
1884
}%
1885
%
1886
\newcommand{\umlVHinherit}[3][]{\umlVHrelation[style={tikzuml inherit style}, #1]{#2}{#3}}%
1887
\newcommand{\umlVHimpl}[3][]{\umlVHrelation[style={tikzuml implements style}, #1]{#2}{#3}}%
1888
\newcommand{\umlVHreal}[3][]{\umlVHrelation[style={tikzuml implements style}, #1]{#2}{#3}}%
1889
\newcommand{\umlVHassoc}[3][]{\umlVHrelation[style={tikzuml association style}, #1]{#2}{#3}}%
1890
\newcommand{\umlVHuniassoc}[3][]{\umlVHrelation[style={tikzuml unidirectional association style}, #1]{#2}{#3}}%
1891
\newcommand{\umlVHaggreg}[3][]{\umlVHrelation[style={tikzuml aggregation style}, #1]{#2}{#3}}%
1892
\newcommand{\umlVHuniaggreg}[3][]{\umlVHrelation[style={tikzuml unidirectional aggregation style}, #1]{#2}{#3}}%
1893
\newcommand{\umlVHcompo}[3][]{\umlVHrelation[style={tikzuml composition style}, #1]{#2}{#3}}%
1894
\newcommand{\umlVHunicompo}[3][]{\umlVHrelation[style={tikzuml unidirectional composition style}, #1]{#2}{#3}}%
1895
\newcommand{\umlVHimport}[3][]{\umlVHrelation[style={tikzuml import style}, #1]{#2}{#3}}%
1896
\newcommand{\umlVHnest}[3][]{\umlVHrelation[style={tikzuml nesting style}, #1]{#2}{#3}}%
1897
\newcommand{\umlVHdep}[3][]{\umlVHrelation[style={tikzuml dependency style}, #1]{#2}{#3}}%
1898
\newcommand{\umlVHfriend}[3][]{%
1899
\pgfkeys{/tikzuml/friendrelation/.cd,%
1900
.unknown/.code={%
1901
\let\keyname=\pgfkeyscurrentname%
1902
\let\keyvalue=\pgfkeyscurrentvalue%
1903
\ifthenelse{\equal{\keyname}{stereo}}{%
1904
\errmessage{TIKZUML ERROR : in umlVHfriend, forbidden option stereo}%
1905
}{%
1906
\ifthenelse{\equal{\keyname}{geometry}}{%
1907
\errmessage{TIKZUML ERROR : in umlVHfriend, forbidden option geometry}%
1908
}{}%
1909
}%
1910
}}%
1911
\pgfkeys{/tikzuml/friendrelation/.cd, #1}%
1912
\umlrelation[geometry=|-, stereo=friend, style={tikzuml dependency style}, #1]{#2}{#3}%
1913
}%
1914
%
1915
\newcommand{\umlHVHinherit}[3][]{\umlHVHrelation[style={tikzuml inherit style}, #1]{#2}{#3}}%
1916
\newcommand{\umlHVHimpl}[3][]{\umlHVHrelation[style={tikzuml implements style}, #1]{#2}{#3}}%
1917
\newcommand{\umlHVHreal}[3][]{\umlHVHrelation[style={tikzuml implements style}, #1]{#2}{#3}}%
1918
\newcommand{\umlHVHassoc}[3][]{\umlHVHrelation[style={tikzuml association style}, #1]{#2}{#3}}%
1919
\newcommand{\umlHVHuniassoc}[3][]{\umlHVHrelation[style={tikzuml unidirectional association style}, #1]{#2}{#3}}%
1920
\newcommand{\umlHVHaggreg}[3][]{\umlHVHrelation[style={tikzuml aggregation style}, #1]{#2}{#3}}%
1921
\newcommand{\umlHVHuniaggreg}[3][]{\umlHVHrelation[style={tikzuml unidirectional aggregation style}, #1]{#2}{#3}}%
1922
\newcommand{\umlHVHcompo}[3][]{\umlHVHrelation[style={tikzuml composition style}, #1]{#2}{#3}}%
1923
\newcommand{\umlHVHunicompo}[3][]{\umlHVHrelation[style={tikzuml unidirectional composition style}, #1]{#2}{#3}}%
1924
\newcommand{\umlHVHimport}[3][]{\umlHVHrelation[style={tikzuml import style}, #1]{#2}{#3}}%
1925
\newcommand{\umlHVHnest}[3][]{\umlHVHrelation[style={tikzuml nesting style}, #1]{#2}{#3}}%
1926
\newcommand{\umlHVHdep}[3][]{\umlHVHrelation[style={tikzuml dependency style}, #1]{#2}{#3}}%
1927
\newcommand{\umlHVHfriend}[3][]{%
1928
\pgfkeys{/tikzuml/friendrelation/.cd,%
1929
.unknown/.code={%
1930
\let\keyname=\pgfkeyscurrentname%
1931
\let\keyvalue=\pgfkeyscurrentvalue%
1932
\ifthenelse{\equal{\keyname}{stereo}}{%
1933
\errmessage{TIKZUML ERROR : in umlHVHfriend, forbidden option stereo}%
1934
}{%
1935
\ifthenelse{\equal{\keyname}{geometry}}{%
1936
\errmessage{TIKZUML ERROR : in umlHVHfriend, forbidden option geometry}%
1937
}{}%
1938
}%
1939
}}%
1940
\pgfkeys{/tikzuml/friendrelation/.cd, #1}%
1941
\umlrelation[geometry=-|-, stereo=friend, style={tikzuml dependency style}, #1]{#2}{#3}%
1942
}%
1943
%
1944
\newcommand{\umlVHVinherit}[3][]{\umlVHVrelation[style={tikzuml inherit style}, #1]{#2}{#3}}%
1945
\newcommand{\umlVHVimpl}[3][]{\umlVHVrelation[style={tikzuml implements style}, #1]{#2}{#3}}%
1946
\newcommand{\umlVHVreal}[3][]{\umlVHVrelation[style={tikzuml implements style}, #1]{#2}{#3}}%
1947
\newcommand{\umlVHVassoc}[3][]{\umlVHVrelation[style={tikzuml association style}, #1]{#2}{#3}}%
1948
\newcommand{\umlVHVuniassoc}[3][]{\umlVHVrelation[style={tikzuml unidirectional association style}, #1]{#2}{#3}}%
1949
\newcommand{\umlVHVaggreg}[3][]{\umlVHVrelation[style={tikzuml aggregation style}, #1]{#2}{#3}}%
1950
\newcommand{\umlVHVuniaggreg}[3][]{\umlVHVrelation[style={tikzuml unidirectional aggregation style}, #1]{#2}{#3}}%
1951
\newcommand{\umlVHVcompo}[3][]{\umlVHVrelation[style={tikzuml composition style}, #1]{#2}{#3}}%
1952
\newcommand{\umlVHVunicompo}[3][]{\umlVHVrelation[style={tikzuml unidirectional composition style}, #1]{#2}{#3}}%
1953
\newcommand{\umlVHVimport}[3][]{\umlVHVrelation[style={tikzuml import style}, #1]{#2}{#3}}%
1954
\newcommand{\umlVHVnest}[3][]{\umlVHVrelation[style={tikzuml nesting style}, #1]{#2}{#3}}%
1955
\newcommand{\umlVHVdep}[3][]{\umlVHVrelation[style={tikzuml dependency style}, #1]{#2}{#3}}%
1956
\newcommand{\umlVHVfriend}[3][]{%
1957
\pgfkeys{/tikzuml/friendrelation/.cd,%
1958
.unknown/.code={%
1959
\let\keyname=\pgfkeyscurrentname%
1960
\let\keyvalue=\pgfkeyscurrentvalue%
1961
\ifthenelse{\equal{\keyname}{stereo}}{%
1962
\errmessage{TIKZUML ERROR : in umlVHVfriend, forbidden option stereo}%
1963
}{%
1964
\ifthenelse{\equal{\keyname}{geometry}}{%
1965
\errmessage{TIKZUML ERROR : in umlVHVfriend, forbidden option geometry}%
1966
}{}%
1967
}%
1968
}}%
1969
\pgfkeys{/tikzuml/friendrelation/.cd, #1}%
1970
\umlrelation[geometry=|-|, stereo=friend, style={tikzuml dependency style}, #1]{#2}{#3}%
1971
}%
1972
%
1973
% define a node
1974
\newcommand{\umlnode}[2]{%
1975
\node (#2) at (#1) {};%
1976
}%
1977
%
1978
% main command to define a relation between two classes through a control node
1979
% args : src class
1980
% control node
1981
% dest class
1982
% optional : arg1, arg2, arg: name of the src/dest/dest side class type attribute defined by the relation
1983
% mult1, mult2, mult: multiplicity of the src/dest/dest side class type attribute defined by the relation
1984
% pos1, pos2, pos: position of the src/dest/dest side class type attribute defined by the relation
1985
% align1, align2, align: text justification of the src/dest/dest side class type attribute defined by the relation
1986
% anchor1, anchor2: src/dest anchors on linked classes
1987
% stereo: stereotype of the relation
1988
% pos stereo: position of the stereotype on the relation
1989
% style: style of the relation (association, aggregation, composition, inherit, ...)
1990
% name: rootname used for naming nodes of the relation
1991
\newcommand{\umlCNrelation}[4][]{%
1992
\pgfkeys{/tikzuml/relation/.cd, arg1/.initial={}, arg2/.initial={}, arg/.initial={},%
1993
mult1/.initial={}, mult2/.initial={}, mult/.initial={},%
1994
pos1/.initial=0.2, pos2/.initial=0.8, pos/.initial=tikzumlEmpty,%
1995
align1/.initial={}, align2/.initial={}, align/.initial={},%
1996
anchor1/.initial=tikzumlEmpty, anchor2/.initial=tikzumlEmpty,%
1997
stereo/.initial={}, pos stereo/.initial=1,%
1998
style/.initial=->, name/.initial=relation-\thetikzumlRelationNum,%
1999
.unknown/.code={%
2000
\let\keyname=\pgfkeyscurrentname%
2001
\let\keyvalue=\pgfkeyscurrentvalue%
2002
\errmessage{TIKZUML ERROR : in umlCNrelation, invalid option \keyname}%
2003
}%
2004
}%
2005
\pgfkeys{/tikzuml/relation/.cd,#1}%
2006
\pgfkeys{/tikzuml/relation/.cd, arg1/.get=\tikzumlCNRelationAttrName, arg2/.get=\tikzumlCNRelationAttrNameTO, arg/.get=\tikzumlCNRelationAttrNameTT,%
2007
mult1/.get=\tikzumlCNRelationMultiplicity, mult2/.get=\tikzumlCNRelationMultiplicityTO, mult/.get=\tikzumlCNRelationMultiplicityTT,%
2008
pos1/.get=\tikzumlCNRelationPosition, pos2/.get=\tikzumlCNRelationPositionTO, pos/.get=\tikzumlCNRelationPositionTT,%
2009
align1/.get=\tikzumlCNRelationAlign, align2/.get=\tikzumlCNRelationAlignTO, align/.get=\tikzumlCNRelationAlignTT,%
2010
anchor1/.get=\tikzumlCNRelationSrcAnchor, anchor2/.get=\tikzumlCNRelationDestAnchor,%
2011
stereo/.get=\tikzumlCNRelationStereoType, pos stereo/.get=\tikzumlCNRelationPositionStereotype,%
2012
style/.get=\tikzumlCNRelationStyle, name/.get=\tikzumlCNRelationName%
2013
}%
2014
%
2015
% managing \_ in class names for node names
2016
\def\tikzumlSrcClassName{#2}%
2017
\begingroup%
2018
\def\_{_}\edef\x{\endgroup%
2019
\def\noexpand\tikzumlSrcClassNodeName{\tikzumlSrcClassName}}\x%
2020
%
2021
\StrSubstitute{\tikzumlSrcClassNodeName}{:}{@COLON@}[\tikzumlSrcClassNodeName]%
2022
\StrSubstitute{\tikzumlSrcClassNodeName}{\_}{@UNDERSCORE@}[\tikzumlSrcClassNodeName]%
2023
%
2024
\def\tikzumlDestClassName{#4}%
2025
\begingroup%
2026
\def\_{_}\edef\x{\endgroup%
2027
\def\noexpand\tikzumlDestClassNodeName{\tikzumlDestClassName}}\x%
2028
%
2029
\StrSubstitute{\tikzumlDestClassNodeName}{:}{@COLON@}[\tikzumlDestClassNodeName]%
2030
\StrSubstitute{\tikzumlDestClassNodeName}{\_}{@UNDERSCORE@}[\tikzumlDestClassNodeName]%
2031
%
2032
% managing alias keys
2033
\def\tikzumlCNRelationAttrNameT{\tikzumlCNRelationAttrNameTO\tikzumlCNRelationAttrNameTT}%
2034
\def\tikzumlCNRelationMultiplicityT{\tikzumlCNRelationMultiplicityTO\tikzumlCNRelationMultiplicityTT}%
2035
\def\tikzumlCNRelationAlignT{\tikzumlCNRelationAlignTO\tikzumlCNRelationAlignTT}%
2036
\def\orientationT{\orientationTO\orientationTT}%
2037
%
2038
\ifthenelse{\equal{\tikzumlCNRelationPositionTT}{tikzumlEmpty}}{%
2039
\def\tikzumlCNRelationPositionT{\tikzumlCNRelationPositionTO}%
2040
}{%
2041
\def\tikzumlCNRelationPositionT{\tikzumlCNRelationPositionTT}%
2042
}%
2043
%
2044
\def\attrAlign{}%
2045
\def\multAlign{}%
2046
\def\attrAlignT{}%
2047
\def\multAlignT{}%
2048
%
2049
\ifthenelse{\equal{\tikzumlCNRelationAlign}{left}}{%
2050
\def\attrAlign{above right}%
2051
\def\multAlign{below right}%
2052
}{%
2053
\ifthenelse{\equal{\tikzumlCNRelationAlign}{right}}{%
2054
\def\attrAlign{above left}%
2055
\def\multAlign{below left}%
2056
}{}%
2057
}%
2058
%
2059
\ifthenelse{\equal{\tikzumlCNRelationAlignT}{left}}{%
2060
\def\attrAlignT{above right}%
2061
\def\multAlignT{below right}%
2062
}{%
2063
\ifthenelse{\equal{\tikzumlCNRelationAlignT}{right}}{%
2064
\def\attrAlignT{above left}%
2065
\def\multAlignT{below left}%
2066
}{}%
2067
}%
2068
%
2069
% def stereotype
2070
\ifthenelse{\equal{\tikzumlCNRelationStereoType}{}}{%
2071
\def\stereotype{}%
2072
}{%
2073
\def\stereotype{$\ll$\tikzumlCNRelationStereoType$\gg$}%
2074
}%
2075
%
2076
% def anchors macros
2077
\ifthenelse{\equal{\tikzumlCNRelationSrcAnchor}{tikzumlEmpty}}{%
2078
\def\tikzumlCNRelationSrcAnchor{}%
2079
}{%
2080
\let\tikzumlCNRelationSrcAnchorold\tikzumlCNRelationSrcAnchor%
2081
\def\tikzumlCNRelationSrcAnchor{.\tikzumlCNRelationSrcAnchorold}%
2082
}%
2083
%
2084
\ifthenelse{\equal{\tikzumlCNRelationDestAnchor}{tikzumlEmpty}}{%
2085
\def\tikzumlCNRelationDestAnchor{}%
2086
}{%
2087
\let\tikzumlCNRelationDestAnchorold\tikzumlCNRelationDestAnchor%
2088
\def\tikzumlCNRelationDestAnchor{.\tikzumlCNRelationDestAnchorold}%
2089
}%
2090
%
2091
\setcounter{pos}{100*\real{\tikzumlCNRelationPosition}}%
2092
\setcounter{posT}{100*\real{\tikzumlCNRelationPositionT}}%
2093
\setcounter{posStereo}{100*\real{\tikzumlCNRelationPositionStereotype}}%
2094
%
2095
% straight line
2096
%\setcounter{tikzumlControlNodesNum}{1}%
2097
%
2098
\def\tikzumlFirstArc{node[midway, name=\tikzumlCNRelationName-1, anchor=center] {} }%
2099
\def\tikzumlLastArc{node[midway, name=\tikzumlCNRelationName-3, anchor=center]{} }%
2100
\def\posAttrName{}%
2101
\def\posMultiplicity{}%
2102
\def\posAttrNameT{}%
2103
\def\posMultiplicityT{}%
2104
%
2105
\begin{pgfonlayer}{connections}%
2106
\node (\tikzumlCNRelationName-2) at (#3) {};%
2107
\end{pgfonlayer}%
2108
%
2109
\ifnum\theposStereo>100%
2110
\pgfmathsetmacro{\tikzumlCNRelationPositionStereotype}{(\theposStereo-100)/100}%
2111
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlCNRelationPositionStereotype, anchor=center] {\stereotype} }%
2112
\else%
2113
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlCNRelationPositionStereotype, anchor=center] {\stereotype} }%
2114
\fi%
2115
%
2116
\ifnum\thepos>100%
2117
\pgfmathsetmacro{\tikzumlCNRelationPosition}{(\thepos-100)/100}%
2118
\def\arcNum{2}%
2119
\else%
2120
\def\arcNum{1}%
2121
\ifnum\thepos=100%
2122
\def\posAttrName{above left}%
2123
\def\posMultiplicity{below right}%
2124
\fi%
2125
\fi%
2126
%
2127
\ifnum\arcNum=1%
2128
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlCNRelationPosition, \posAttrName, \attrAlign] {\tikzumlCNRelationAttrName}%
2129
node[pos=\tikzumlCNRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlCNRelationMultiplicity} }%
2130
\fi%
2131
\ifnum\arcNum=2%
2132
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlCNRelationPosition, \posAttrName, \attrAlign] {\tikzumlCNRelationAttrName}%
2133
node[pos=\tikzumlCNRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlCNRelationMultiplicity} }%
2134
\fi%
2135
%
2136
\ifnum\theposT>100%
2137
\pgfmathsetmacro{\tikzumlCNRelationPositionT}{(\theposT-100)/100}%
2138
\def\arcNumT{2}%
2139
\else%
2140
\def\arcNumT{1}%
2141
\ifnum\theposT=100%
2142
\def\posAttrNameT{above left}%
2143
\def\posMultiplicityT{below right}%
2144
\fi%
2145
\fi%
2146
%
2147
\ifnum\arcNumT=1%
2148
\xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlCNRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlCNRelationAttrNameT}%
2149
node[pos=\tikzumlCNRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlCNRelationMultiplicityT} }%
2150
\fi%
2151
\ifnum\arcNumT=2%
2152
\xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlCNRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlCNRelationAttrNameT}%
2153
node[pos=\tikzumlCNRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlCNRelationMultiplicityT} }%
2154
\fi%
2155
%
2156
\xdef\tikzumlPath{(\tikzumlSrcClassNodeName\tikzumlCNRelationSrcAnchor) -- \tikzumlFirstArc (\tikzumlCNRelationName-2.base) -- \tikzumlLastArc (\tikzumlDestClassNodeName\tikzumlCNRelationDestAnchor) }%
2157
2158
\begin{pgfonlayer}{connections}%
2159
\ifthenelse{\equal{\tikzumlCNRelationStyle}{tikzuml nesting style}}{%
2160
\pgfarrowsdeclare{nested}{nested}{...}
2161
{
2162
\tikzumlNestingSymbolSize=0.2pt%
2163
\advance\tikzumlNestingSymbolSize by .5\pgflinewidth%
2164
\pgfsetdash{}{0pt} % do not dash
2165
\pgfsetroundjoin % fix join
2166
\pgfsetroundcap % fix cap
2167
\pgfpathmoveto{\pgfpoint{-16*\tikzumlNestingSymbolSize}{0pt}}%
2168
\pgfpatharc{180}{90}{8*\tikzumlNestingSymbolSize}%
2169
\pgfpatharc{90}{0}{8*\tikzumlNestingSymbolSize}%
2170
\pgfpatharc{0}{-90}{8*\tikzumlNestingSymbolSize}%
2171
\pgfpatharc{-90}{-180}{8*\tikzumlNestingSymbolSize}%
2172
\pgfpathmoveto{\pgfpoint{-8*\tikzumlNestingSymbolSize}{8*\tikzumlNestingSymbolSize}}%
2173
\pgfpathlineto{\pgfpoint{-8*\tikzumlNestingSymbolSize}{-8*\tikzumlNestingSymbolSize}}%
2174
\pgfusepathqstroke%
2175
}%
2176
\draw[auto, \tikzumlCNRelationStyle, nested-, font=\tikzumlDefaultFont] \tikzumlPath ;%
2177
}{
2178
\draw[auto, \tikzumlCNRelationStyle, font=\tikzumlDefaultFont] \tikzumlPath ;%
2179
}
2180
\end{pgfonlayer}%
2181
%
2182
\stepcounter{tikzumlRelationNum}%
2183
}%
2184
%
2185
% shortcuts for cnrelations
2186
\newcommand{\umlCNinherit}[4][]{\umlCNrelation[style={tikzuml inherit style}, #1]{#2}{#3}{#4}}%
2187
\newcommand{\umlCNimpl}[4][]{\umlCNrelation[style={tikzuml implements style}, #1]{#2}{#3}{#4}}%
2188
\newcommand{\umlCNreal}[4][]{\umlCNrelation[style={tikzuml implements style}, #1]{#2}{#3}{#4}}%
2189
\newcommand{\umlCNassoc}[4][]{\umlCNrelation[style={tikzuml association style}, #1]{#2}{#3}{#4}}%
2190
\newcommand{\umlCNuniassoc}[4][]{\umlCNrelation[style={tikzuml unidirectional association style}, #1]{#2}{#3}{#4}}%
2191
\newcommand{\umlCNaggreg}[4][]{\umlCNrelation[style={tikzuml aggregation style}, #1]{#2}{#3}{#4}}%
2192
\newcommand{\umlCNuniaggreg}[4][]{\umlCNrelation[style={tikzuml unidirectional aggregation style}, #1]{#2}{#3}{#4}}%
2193
\newcommand{\umlCNcompo}[4][]{\umlCNrelation[style={tikzuml composition style}, #1]{#2}{#3}{#4}}%
2194
\newcommand{\umlCNunicompo}[4][]{\umlCNrelation[style={tikzuml unidirectional composition style}, #1]{#2}{#3}{#4}}%
2195
\newcommand{\umlCNimport}[4][]{\umlCNrelation[style={tikzuml import style}, #1]{#2}{#3}{#4}}%
2196
\newcommand{\umlCNnest}[4][]{\umlCNrelation[style={tikzuml nesting style}, #1]{#2}{#3}{#4}}%
2197
\newcommand{\umlCNdep}[4][]{\umlCNrelation[style={tikzuml dependency style}, #1]{#2}{#3}{#4}}%
2198
\newcommand{\umlCNfriend}[4][]{%
2199
\pgfkeys{/tikzuml/friendrelation/.cd,%
2200
.unknown/.code={%
2201
\let\keyname=\pgfkeyscurrentname%
2202
\let\keyvalue=\pgfkeyscurrentvalue%
2203
\ifthenelse{\equal{\keyname}{stereo}}{%
2204
\errmessage{TIKZUML ERROR : in umlCNfriend, forbidden option stereo}%
2205
}{}%
2206
}}%
2207
\pgfkeys{/tikzuml/friendrelation/.cd, #1}%
2208
\umlCNrelation[stereo=friend, style={tikzuml dependency style}, #1]{#2}{#3}{#4}%
2209
}%
2210
%
2211
% define a note
2212
% arg : attached class
2213
% label of the note
2214
% optional : x,y: coordinates of the note
2215
% width: width of the note
2216
% geometry: geometry of the relation between the note and what it is about
2217
% weight: barycentric weight for a 3-line relation
2218
% arm: length of the first arm
2219
% anchor1, anchor2: anchors of the relation
2220
% draw, fill, text: colors
2221
% style: to manage every default TikZ option
2222
% no coords: to tell that the note position is defined relatively
2223
% to another node (automatically used with TikZ options above, below, left, right, below left, ...)
2224
\newcommand{\umlnote}[3][]{%
2225
\pgfkeys{/tikzuml/note/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlNoteDefaultWidth,%
2226
geometry/.initial=\tikzumlRelationDefaultGeometry,%
2227
weight/.initial=\tikzumlRelationDefaultWeight, arm/.initial=auto, style/.style={},%
2228
anchor1/.initial=tikzumlEmpty, anchor2/.initial=tikzumlEmpty,%
2229
draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlNoteDefaultFillColor,%
2230
text/.initial=\tikzumlDefaultTextColor,%
2231
no coords/.is if=tikzumlnoteWithoutCoords,%
2232
no coords=false,%
2233
.unknown/.code={%
2234
\let\keyname=\pgfkeyscurrentname%
2235
\let\keyvalue=\pgfkeyscurrentvalue%
2236
\ifthenelse{\equal{\keyname}{above}\OR%
2237
\equal{\keyname}{left}\OR%
2238
\equal{\keyname}{below}\OR%
2239
\equal{\keyname}{right}\OR%
2240
\equal{\keyname}{above left}\OR%
2241
\equal{\keyname}{above right}\OR%
2242
\equal{\keyname}{below left}\OR%
2243
\equal{\keyname}{below right}}{%
2244
\IfSubStr{\keyvalue}{ of }{%
2245
\pgfkeys{/tikzuml/note/.cd, no coords}%
2246
}{}%
2247
}{}%
2248
\ifx\keyvalue\pgfkeysnovalue%
2249
\pgfkeys{/tikzuml/note/.cd, style/.append style/.expand once={\keyname}}%
2250
\else%
2251
\pgfkeys{/tikzuml/note/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
2252
\fi%
2253
%\errmessage{TIKZUML ERROR : in umlnote, invalid option \keyname}%
2254
}%
2255
}%
2256
\pgfkeys{/tikzuml/note/.cd, #1}%
2257
\pgfkeys{/tikzuml/note/.cd, x/.get=\tikzumlNoteX, y/.get=\tikzumlNoteY, width/.get=\tikzumlNoteTextWidth,%
2258
geometry/.get=\tikzumlNoteGeometry,%
2259
weight/.get=\tikzumlNoteWeight, arm/.get=\tikzumlNoteArm,%
2260
anchor1/.get=\tikzumlNoteSrcAnchor, anchor2/.get=\tikzumlNoteDestAnchor,%
2261
draw/.get=\tikzumlNoteDrawColor, fill/.get=\tikzumlNoteFillColor,%
2262
text/.get=\tikzumlNoteTextColor%
2263
}%
2264
%
2265
\def\tikzumlClassName{#2}%
2266
\begingroup%
2267
\def\_{_}\edef\x{\endgroup%
2268
\def\noexpand\tikzumlClassNodeName{\tikzumlClassName}}\x%
2269
%
2270
% def anchors macros
2271
\ifthenelse{\equal{\tikzumlNoteSrcAnchor}{tikzumlEmpty}}{%
2272
\def\tikzumlNoteSrcAnchor{}%
2273
}{%
2274
\let\tikzumlNoteSrcAnchorold\tikzumlNoteSrcAnchor%
2275
\def\tikzumlNoteSrcAnchor{.\tikzumlNoteSrcAnchorold}%
2276
}%
2277
%
2278
\ifthenelse{\equal{\tikzumlNoteDestAnchor}{tikzumlEmpty}}{%
2279
\def\tikzumlNoteDestAnchor{}%
2280
}{%
2281
\let\tikzumlNoteDestAnchorold\tikzumlNoteDestAnchor%
2282
\def\tikzumlNoteDestAnchor{.\tikzumlNoteDestAnchorold}%
2283
}%
2284
%
2285
\iftikzumlnoteWithoutCoords%
2286
\node[text=\tikzumlNoteTextColor, text width=\tikzumlNoteTextWidth, font=\tikzumlDefaultFont, outer sep=0, inner xsep=1ex, inner ysep=3ex, /tikzuml/note/style] (note-\thetikzumlNoteNum-coord) {#3};%
2287
\else%
2288
\node[text=\tikzumlNoteTextColor, text width=\tikzumlNoteTextWidth, font=\tikzumlDefaultFont, outer sep=0, inner xsep=1ex, inner ysep=3ex, /tikzuml/note/style] (note-\thetikzumlNoteNum-coord) at (\tikzumlNoteX, \tikzumlNoteY) {#3};%
2289
\fi%
2290
\draw (note-\thetikzumlNoteNum-coord.north east) node[name=note-\thetikzumlNoteNum-right-top, below=2ex, coordinate] {};%
2291
\draw (note-\thetikzumlNoteNum-coord.north east) node[name=note-\thetikzumlNoteNum-top-right, left=2ex, coordinate] {};%
2292
\draw[draw=\tikzumlNoteDrawColor, fill=\tikzumlNoteFillColor] (note-\thetikzumlNoteNum-coord.south west) -- (note-\thetikzumlNoteNum-coord.south east) -- (note-\thetikzumlNoteNum-right-top.base) -- (note-\thetikzumlNoteNum-top-right.base) -- (note-\thetikzumlNoteNum-coord.north west) -- cycle;%
2293
\node[text=\tikzumlNoteTextColor, text width=\tikzumlNoteTextWidth, outer sep=0, inner xsep=1ex, inner ysep=3ex, font=\tikzumlDefaultFont] (note-\thetikzumlNoteNum) at (note-\thetikzumlNoteNum-coord) {#3};%
2294
\draw[draw=\tikzumlNoteDrawColor] (note-\thetikzumlNoteNum-right-top) -| (note-\thetikzumlNoteNum-top-right);%
2295
%
2296
\pgfmathsetmacro{\tikzumlNoteWeightT}{1.0-\tikzumlNoteWeight}%
2297
\node (note-\thetikzumlNoteNum-middle) at (barycentric cs:note-\thetikzumlNoteNum-coord=\tikzumlNoteWeight,\tikzumlClassNodeName=\tikzumlNoteWeightT) {};%
2298
%
2299
\ifthenelse{\equal{\tikzumlNoteGeometry}{--}%
2300
\OR\equal{\tikzumlNoteGeometry}{-|}%
2301
\OR\equal{\tikzumlNoteGeometry}{|-}}{%
2302
\edef\tikzumlnotepath{\tikzumlNoteGeometry}
2303
}{%
2304
\ifthenelse{\equal{\tikzumlNoteGeometry}{-|-}}{%
2305
\ifthenelse{\equal{\tikzumlNoteArm}{auto}}{%
2306
\edef\tikzumlnotepath{-- (note-\thetikzumlNoteNum-coord\tikzumlNoteSrcAnchor -| note-\thetikzumlNoteNum-middle.center) -- (note-\thetikzumlNoteNum-middle.center) -- (note-\thetikzumlNoteNum-middle.center |- \tikzumlClassNodeName\tikzumlNoteDestAnchor) --}%
2307
}{%
2308
\draw (note-\thetikzumlNoteNum-coord\tikzumlNoteSrcAnchor)+(\tikzumlNoteArm,0) node[name=note-\thetikzumlNoteNum-tmp] {};
2309
\edef\tikzumlnotepath{-- (note-\thetikzumlNoteNum-tmp.center) |-}%
2310
}%
2311
}{%
2312
\ifthenelse{\equal{\tikzumlNoteGeometry}{|-|}}{%
2313
\ifthenelse{\equal{\tikzumlNoteArm}{auto}}{%
2314
\edef\tikzumlnotepath{-- (note-\thetikzumlNoteNum-coord\tikzumlNoteSrcAnchor |- note-\thetikzumlNoteNum-middle.center) -- (note-\thetikzumlNoteNum-middle.center) -- (note-\thetikzumlNoteNum-middle.center -| \tikzumlClassNodeName\tikzumlNoteDestAnchor) --}%
2315
}{%
2316
\draw (note-\thetikzumlNoteNum-coord\tikzumlNoteSrcAnchor)+(0,\tikzumlNoteArm) node[name=note-\thetikzumlNoteNum-tmp] {};
2317
\edef\tikzumlnotepath{-- (note-\thetikzumlNoteNum-tmp.center) -|}%
2318
}%
2319
2320
}{%
2321
\errmessage{TIKZUML ERROR : Unknown geometry value !!! It should be in the following list : --, |-, -|, |-|, -|-}%
2322
}%
2323
}%
2324
}%
2325
%
2326
\begin{pgfonlayer}{connections}%
2327
\draw[dashed] (note-\thetikzumlNoteNum-coord\tikzumlNoteSrcAnchor) \tikzumlnotepath (\tikzumlClassNodeName\tikzumlNoteDestAnchor);%
2328
\end{pgfonlayer}%
2329
%
2330
\stepcounter{tikzumlNoteNum}%
2331
}%
2332
%
2333
% shortcuts for note with geometry
2334
\newcommand{\umlHVnote}[3][]{%
2335
\pgfkeys{/tikzuml/note/.cd,%
2336
.unknown/.code={%
2337
\let\keyname=\pgfkeyscurrentname%
2338
\let\keyvalue=\pgfkeyscurrentvalue%
2339
\ifthenelse{\equal{\keyname}{geometry}}{%
2340
\errmessage{TIKZUML ERROR : in umlHVnote, forbidden option geometry}%
2341
}{}%
2342
}}%
2343
\pgfkeys{/tikzuml/note/.cd, #1}%
2344
\umlnote[geometry=-|, #1]{#2}{#3}%
2345
}%
2346
\newcommand{\umlVHnote}[3][]{%
2347
\pgfkeys{/tikzuml/note/.cd,%
2348
.unknown/.code={%
2349
\let\keyname=\pgfkeyscurrentname%
2350
\let\keyvalue=\pgfkeyscurrentvalue%
2351
\ifthenelse{\equal{\keyname}{geometry}}{%
2352
\errmessage{TIKZUML ERROR : in umlVHnote, forbidden option geometry}%
2353
}{}%
2354
}}%
2355
\pgfkeys{/tikzuml/note/.cd, #1}%
2356
\umlnote[geometry=|-, #1]{#2}{#3}%
2357
}%
2358
\newcommand{\umlVHVnote}[3][]{%
2359
\pgfkeys{/tikzuml/note/.cd,%
2360
.unknown/.code={%
2361
\let\keyname=\pgfkeyscurrentname%
2362
\let\keyvalue=\pgfkeyscurrentvalue%
2363
\ifthenelse{\equal{\keyname}{geometry}}{%
2364
\errmessage{TIKZUML ERROR : in umlVHVnote, forbidden option geometry}%
2365
}{}%
2366
}}%
2367
\pgfkeys{/tikzuml/note/.cd, #1}%
2368
\umlnote[geometry=|-|, #1]{#2}{#3}%
2369
}%
2370
\newcommand{\umlHVHnote}[3][]{%
2371
\pgfkeys{/tikzuml/note/.cd,%
2372
.unknown/.code={%
2373
\let\keyname=\pgfkeyscurrentname%
2374
\let\keyvalue=\pgfkeyscurrentvalue%
2375
\ifthenelse{\equal{\keyname}{geometry}}{%
2376
\errmessage{TIKZUML ERROR : in umlHVHnote, forbidden option geometry}%
2377
}{}%
2378
}}%
2379
\pgfkeys{/tikzuml/note/.cd, #1}%
2380
\umlnote[geometry=-|-, #1]{#2}{#3}%
2381
}%
2382
%
2383
% define a uml association class (command)
2384
% args : name of the class
2385
% attributes of the class
2386
% operations of the class
2387
% optional : x,y: coordinates of the class
2388
% width: width of the class node
2389
% type: type of of class (class, interface, typedef, enum)
2390
% template: template parameters
2391
% name: name of the class node
2392
% geometry: geometry of the line
2393
% weight: barycentric weight of the middle part when geometry is a 3-line
2394
% arm: length of first part when geometry id a 3-line
2395
% anchor1, anchor2: src/dest anchors on linked classes
2396
% style: style of the association class (association, aggregation, composition, inherit, ...)
2397
% draw, fill, fill template, text: colors
2398
% style: to manage every default TikZ option
2399
% no coords: to tell that the class position is defined relatively
2400
% to another node (automatically used with TikZ options above, below, left, right, below left, ...)
2401
\newcommand{\umlassocclass}[5][]{%
2402
\pgfkeys{/tikzuml/assocclass/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX,
2403
width/.initial=\tikzumlClassDefaultWidth, type/.initial=\tikzumlClassDefaultType, style/.style={},%
2404
template/.initial={}, name/.initial=tikzumlEmpty, geometry/.initial=\tikzumlRelationDefaultGeometry,%
2405
weight/.initial=\tikzumlRelationDefaultWeight, arm/.initial=auto,%
2406
anchor1/.initial=tikzumlEmpty, anchor2/.initial=tikzumlEmpty,%
2407
draw/.initial=\tikzumlDefaultDrawColor,%
2408
fill template/.initial=\tikzumlClassTemplateFillColorDefaultFillColor,%
2409
fill/.initial=\tikzumlClassDefaultFillColor,%
2410
text/.initial=\tikzumlDefaultTextColor,%
2411
no coords/.is if=tikzumlassocclassWithoutCoords,%
2412
no coords=false,%
2413
.unknown/.code={%
2414
\let\keyname=\pgfkeyscurrentname%
2415
\let\keyvalue=\pgfkeyscurrentvalue%
2416
\ifthenelse{\equal{\keyname}{above}\OR%
2417
\equal{\keyname}{left}\OR%
2418
\equal{\keyname}{below}\OR%
2419
\equal{\keyname}{right}\OR%
2420
\equal{\keyname}{above left}\OR%
2421
\equal{\keyname}{above right}\OR%
2422
\equal{\keyname}{below left}\OR%
2423
\equal{\keyname}{below right}}{%
2424
\IfSubStr{\keyvalue}{ of }{%
2425
\pgfkeys{/tikzuml/assocclass/.cd, no coords}%
2426
}{}%
2427
}{}%
2428
\ifx\keyvalue\pgfkeysnovalue%
2429
\pgfkeys{/tikzuml/assocclass/.cd, style/.append style/.expand once={\keyname}}%
2430
\else%
2431
\pgfkeys{/tikzuml/assocclass/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
2432
\fi%
2433
%\errmessage{TIKZUML ERROR : in umlassocclass, invalid option \keyname}%
2434
}%
2435
}%
2436
%
2437
\pgfkeys{/tikzuml/assocclass/.cd,#1}%
2438
\pgfkeys{/tikzuml/assocclass/.cd, x/.get=\tikzumlAssocClassX, y/.get=\tikzumlAssocClassY,%
2439
width/.get=\tikzumlAssocClassMinimumWidth, type/.get=\tikzumlAssocClassTypeTmp,%
2440
template/.get=\tikzumlAssocClassTemplateParam,%
2441
name/.get=\tikzumlAssocClassName, geometry/.get=\tikzumlAssocClassGeometry,%
2442
weight/.get=\tikzumlAssocClassWeight, arm/.get=\tikzumlAssocClassArm,%
2443
anchor1/.get=\tikzumlAssocClassSrcAnchor,%
2444
anchor2/.get=\tikzumlAssocClassDestAnchor,%
2445
draw/.get=\tikzumlAssocClassDrawColor, fill/.get=\tikzumlAssocClassFillColor,%
2446
text/.get=\tikzumlAssocClassTextColor, fill template/.get=\tikzumlAssocClassTemplateFillColor%
2447
}%
2448
%
2449
\ifthenelse{\equal{\tikzumlAssocClassTypeTmp}{class}\OR\equal{\tikzumlAssocClassTypeTmp}{abstract}}{%
2450
\def\tikzumlAssocClassType{}%
2451
}{%
2452
\def\tikzumlAssocClassType{$\ll$\tikzumlAssocClassTypeTmp$\gg$ \\}%
2453
}%
2454
%
2455
\ifthenelse{\equal{\tikzumlAssocClassTemplateParam}{}}{%
2456
\def\tikzumlAssocClassVPadding{}%
2457
\def\tikzumlAssocClassHPadding{}%
2458
}{%
2459
\def\tikzumlAssocClassVPadding{\vspace{0.1em} \\}%
2460
\def\tikzumlAssocClassHPadding{\hspace{0.5ex} $ $}%
2461
}%
2462
%
2463
\def\tikzumlAssocClassName{#2}%
2464
\def\tikzumlAssocClassRelationName{#3}%
2465
%
2466
\begingroup%
2467
\def\_{_}\edef\x{\endgroup%
2468
\def\noexpand\tikzumlAssocClassNodeName{\tikzumlAssocClassName}}\x%
2469
%
2470
\begingroup%
2471
\def\_{_}\edef\x{\endgroup%
2472
\def\noexpand\tikzumlAssocClassRelationNodeName{\tikzumlAssocClassRelationName}}\x%
2473
%
2474
\ifthenelse{\equal{\tikzumlAssocClassName}{tikzumlEmpty}}{}{%
2475
\def\tikzumlAssocClassNodeName{\tikzumlAssocClassName}%
2476
}%
2477
%
2478
\StrSubstitute{\tikzumlAssocClassNodeName}{:}{@COLON@}[\tikzumlAssocClassNodeName]%
2479
\StrSubstitute{\tikzumlAssocClassNodeName}{\_}{@UNDERSCORE@}[\tikzumlAssocClassNodeName]%
2480
%
2481
\ifthenelse{\equal{\tikzumlAssocClassTypeTmp}{abstract}}{%
2482
\let\tikzumlAssocClassNameOld\tikzumlAssocClassName%
2483
\def\tikzumlAssocClassName{{\it \tikzumlAssocClassNameOld}}%
2484
}{}%
2485
%
2486
\def\tikzumlAssocClassPos{\tikzumlAssocClassX,\tikzumlAssocClassY}%
2487
\def\tikzumlAssocClassAttributes{#4}%
2488
\def\tikzumlAssocClassOperations{#5}%
2489
%
2490
% def anchors macros
2491
\ifthenelse{\equal{\tikzumlAssocClassSrcAnchor}{tikzumlEmpty}}{%
2492
\def\tikzumlAssocClassSrcAnchor{}%
2493
}{%
2494
\let\tikzumlAssocClassSrcAnchorold\tikzumlAssocClassSrcAnchor%
2495
\def\tikzumlAssocClassSrcAnchor{.\tikzumlAssocClassSrcAnchorold}%
2496
}%
2497
%
2498
\ifthenelse{\equal{\tikzumlAssocClassDestAnchor}{tikzumlEmpty}}{%
2499
\def\tikzumlAssocClassDestAnchor{}%
2500
}{%
2501
\let\tikzumlAssocClassDestAnchorold\tikzumlAssocClassDestAnchor%
2502
\def\tikzumlAssocClassDestAnchor{.\tikzumlAssocClassDestAnchorold}%
2503
}%
2504
%
2505
\iftikzumlassocclassWithoutCoords%
2506
\node[tikzuml class style, draw=\tikzumlAssocClassDrawColor, fill=\tikzumlAssocClassFillColor, text=\tikzumlAssocClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlAssocClassMinimumWidth, /tikzuml/assocclass/style] (\tikzumlAssocClassNodeName) {\begin{tabular}{c}\tikzumlAssocClassVPadding \tikzumlAssocClassType \tikzumlAssocClassHPadding \textbf{\tikzumlAssocClassName} \tikzumlAssocClassHPadding \end{tabular}%
2507
\nodepart{second}%
2508
\begin{tabular}{l}%
2509
\tikzumlAssocClassAttributes%
2510
\end{tabular}%
2511
\nodepart{third}%
2512
\begin{tabular}{l}%
2513
\tikzumlAssocClassOperations%
2514
\end{tabular}%
2515
};%
2516
\else%
2517
\node[tikzuml class style, draw=\tikzumlAssocClassDrawColor, fill=\tikzumlAssocClassFillColor, text=\tikzumlAssocClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlAssocClassMinimumWidth, /tikzuml/assocclass/style] (\tikzumlAssocClassNodeName) at (\tikzumlAssocClassPos) {\begin{tabular}{c}\tikzumlAssocClassVPadding \tikzumlAssocClassType \tikzumlAssocClassHPadding \textbf{\tikzumlAssocClassName} \tikzumlAssocClassHPadding \end{tabular}%
2518
\nodepart{second}%
2519
\begin{tabular}{l}%
2520
\tikzumlAssocClassAttributes%
2521
\end{tabular}%
2522
\nodepart{third}%
2523
\begin{tabular}{l}%
2524
\tikzumlAssocClassOperations%
2525
\end{tabular}%
2526
};%
2527
\fi%
2528
%
2529
\ifthenelse{\equal{\tikzumlAssocClassTemplateParam}{}}{}{%
2530
\draw (\tikzumlAssocClassNodeName.north east) node[tikzuml template style, name=\tikzumlAssocClassNodeName-template, draw=\tikzumlAssocClassDrawColor, fill=\tikzumlAssocClassTemplateFillColor, text=\tikzumlAssocClassTextColor, font=\tikzumlDefaultFont] {\tikzumlAssocClassTemplateParam};%
2531
}%
2532
%
2533
\pgfmathsetmacro{\tikzumlAssocClassWeightT}{1.0-\tikzumlAssocClassWeight}
2534
\node (\tikzumlAssocClassNodeName-middle) at (barycentric cs:\tikzumlAssocClassNodeName=\tikzumlAssocClassWeight,\tikzumlAssocClassRelationNodeName=\tikzumlAssocClassWeightT) {};%
2535
%
2536
\ifthenelse{\equal{\tikzumlAssocClassGeometry}{--}\OR\equal{\tikzumlAssocClassGeometry}{-|}\OR\equal{\tikzumlAssocClassGeometry}{|-}}{%
2537
\edef\tikzumlassocclasspath{\tikzumlAssocClassGeometry}
2538
}{%
2539
\ifthenelse{\equal{\tikzumlAssocClassGeometry}{-|-}}{%
2540
\ifthenelse{\equal{\tikzumlAssocClassArm}{auto}}{%
2541
\edef\tikzumlassocclasspath{-- (\tikzumlAssocClassNodeName\tikzumlAssocClassSrcAnchor -| \tikzumlAssocClassNodeName-middle.center) -- (\tikzumlAssocClassNodeName-middle.center) -- (\tikzumlAssocClassNodeName-middle.center |- \tikzumlAssocClassRelationNodeName\tikzumlAssocClassDestAnchor) --}%
2542
}{%
2543
\draw (\tikzumlAssocClassNodeName\tikzumlAssocClassSrcAnchor)+(\tikzumlAssocClassArm,0) node[name=\tikzumlAssocClassNodeName-tmp] {};
2544
\edef\tikzumlnotepath{-- (\tikzumlAssocClassNodeName-tmp.center) |-}%
2545
}%
2546
}{%
2547
\ifthenelse{\equal{\tikzumlAssocClassGeometry}{|-|}}{%
2548
\ifthenelse{\equal{\tikzumlAssocClassArm}{auto}}{%
2549
\edef\tikzumlassocclasspath{-- (\tikzumlAssocClassNodeName\tikzumlAssocClassSrcAnchor |- \tikzumlAssocClassNodeName-middle.center) -- (\tikzumlAssocClassNodeName-middle.center) -- (\tikzumlAssocClassNodeName-middle.center -| \tikzumlAssocClassRelationNodeName\tikzumlAssocClassDestAnchor) --}%
2550
}{%
2551
\draw (\tikzumlAssocClassNodeName\tikzumlAssocClassSrcAnchor)+(0,\tikzumlAssocClassArm) node[name=\tikzumlAssocClassNodeName-tmp] {};
2552
\edef\tikzumlassocclasspath{-- (\thetikzumlAssocClassNodeName-tmp.center) -|}%
2553
}%
2554
2555
}{%
2556
\errmessage{TIKZUML ERROR : Unknown geometry value !!! It should be in the following list : --, |-, -|, |-|, -|-}%
2557
}%
2558
}%
2559
}%
2560
%
2561
\begin{pgfonlayer}{connections}%
2562
\draw[dashed] (\tikzumlAssocClassNodeName\tikzumlAssocClassSrcAnchor) \tikzumlassocclasspath (\tikzumlAssocClassRelationNodeName\tikzumlAssocClassDestAnchor);%
2563
\end{pgfonlayer}%
2564
%
2565
% add to fit
2566
\ifnum\c@tikzumlPackageLevel>0%
2567
\edef\tikzumlPackageFitOld{\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname}%
2568
\ifthenelse{\equal{\tikzumlAssocClassTemplateParam}{}}{%
2569
\expandafter\xdef\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname{\tikzumlPackageFitOld (\tikzumlAssocClassNodeName)(\tikzumlAssocClassNodeName-middle)}%
2570
}{%
2571
\expandafter\xdef\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname{\tikzumlPackageFitOld (\tikzumlAssocClassNodeName) (\tikzumlAssocClassNodeName-template)(\tikzumlAssocClassNodeName-middle)}%
2572
}%
2573
\stepcounter{tikzumlPackageClassNum}%
2574
\fi%
2575
}%
2576
%
2577
%
2578
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2579
% use case diagrams %
2580
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2581
%
2582
\tikzstyle{tikzuml usecase style}=[ellipse, text centered]%
2583
\tikzstyle{tikzuml actor style}=[ellipse, inner sep=0, outer sep=0]%
2584
%
2585
\newcounter{tikzumlSystemUseCaseNum}%
2586
\newcounter{tikzumlSystemLevel}%
2587
\newcounter{tikzumlUseCaseNum}%
2588
\newcounter{tikzumlActorNum}%
2589
%
2590
\newif\iftikzumlusecaseWithoutCoords%
2591
\newif\iftikzumlactorWithoutCoords%
2592
%
2593
% define a system
2594
% arg : name
2595
% optional : x, y: coordinates of the system
2596
% draw, fill, text: colors
2597
\newenvironment{umlsystem}[2][]{%
2598
\gdef\tikzumlSystemFit{}%
2599
\def\tikzumlSystemName{#2}%
2600
\setcounter{tikzumlSystemUseCaseNum}{0}%
2601
%
2602
\pgfkeys{/tikzuml/system/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX,%
2603
draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlSystemDefaultFillColor,%
2604
text/.initial=\tikzumlDefaultTextColor,%
2605
.unknown/.code={%
2606
\let\keyname=\pgfkeyscurrentname%
2607
\let\keyvalue=\pgfkeyscurrentvalue%
2608
\errmessage{TIKZUML ERROR : in umlsystem, invalid option \keyname}%
2609
}%
2610
}%
2611
%
2612
\pgfkeys{/tikzuml/system/.cd, #1}%
2613
\pgfkeys{/tikzuml/system/.cd, x/.get=\tikzumlSystemXShift, y/.get=\tikzumlSystemYShift,%
2614
draw/.get=\tikzumlSystemDrawColor, fill/.get=\tikzumlSystemFillColor,%
2615
text/.get=\tikzumlSystemTextColor}%
2616
%
2617
\stepcounter{tikzumlSystemLevel}%
2618
%
2619
\begin{scope}[xshift=\tikzumlSystemXShift cm, yshift=\tikzumlSystemYShift cm]%
2620
}{%
2621
\addtocounter{tikzumlSystemLevel}{-1}%
2622
% if contains no usecase, one define a fictive node to enable the fit option
2623
\ifnum\c@tikzumlSystemUseCaseNum=0%
2624
\node[inner xsep=10ex, inner ysep=1em] (\tikzumlSystemName-root) at (0,0) {};%
2625
\xdef\tikzumlSystemFit{(\tikzumlSystemName-root)}%
2626
\fi%
2627
%
2628
\begin{pgfonlayer}{background}%
2629
\node[inner ysep=1em, inner xsep=2ex, fit = \tikzumlSystemFit] (\tikzumlSystemName-tmp) {};%
2630
\node[text=\tikzumlSystemTextColor, font=\tikzumlDefaultFont] (\tikzumlSystemName-caption-tmp) at (\tikzumlSystemName-tmp.north) {\tikzumlSystemName};%
2631
\node[draw=\tikzumlSystemDrawColor, fill=\tikzumlSystemFillColor, text=\tikzumlSystemTextColor, font=\tikzumlDefaultFont, inner ysep=1em, inner xsep=2ex, fit = (\tikzumlSystemName-tmp) (\tikzumlSystemName-caption-tmp)] (\tikzumlSystemName) {};%
2632
\node[text=\tikzumlSystemTextColor, font=\tikzumlDefaultFont] (\tikzumlSystemName-caption) at (\tikzumlSystemName-caption-tmp.north) {\tikzumlSystemName};%
2633
\end{pgfonlayer}%
2634
\end{scope}%
2635
%
2636
}%
2637
%
2638
% define a use case
2639
% arg : label of the use case
2640
% optional : x, y: coordinates of the use case
2641
% name: name of the node
2642
% width: node width
2643
% draw, fill, text: colors
2644
% style: to manage every default TikZ option
2645
% no coords: to tell that the use case position is defined relatively
2646
% to another node (automatically used with TikZ options above, below, left, right, below left, ...)
2647
\newcommand{\umlusecase}[2][]{%
2648
\stepcounter{tikzumlUseCaseNum}%
2649
\pgfkeys{/tikzuml/usecase/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=auto,%
2650
name/.initial=usecase-\thetikzumlUseCaseNum,%
2651
draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlUseCaseDefaultFillColor,%
2652
text/.initial=\tikzumlDefaultTextColor, style/.style={},%
2653
no coords/.is if=tikzumlusecaseWithoutCoords,%
2654
no coords=false,%
2655
.unknown/.code={%
2656
\let\keyname=\pgfkeyscurrentname%
2657
\let\keyvalue=\pgfkeyscurrentvalue%
2658
\ifthenelse{\equal{\keyname}{above}\OR%
2659
\equal{\keyname}{left}\OR%
2660
\equal{\keyname}{below}\OR%
2661
\equal{\keyname}{right}\OR%
2662
\equal{\keyname}{above left}\OR%
2663
\equal{\keyname}{above right}\OR%
2664
\equal{\keyname}{below left}\OR%
2665
\equal{\keyname}{below right}}{%
2666
\IfSubStr{\keyvalue}{ of }{%
2667
\pgfkeys{/tikzuml/usecase/.cd, no coords}%
2668
}{}%
2669
}{}%
2670
\ifx\keyvalue\pgfkeysnovalue%
2671
\pgfkeys{/tikzuml/usecase/.cd, style/.append style/.expand once={\keyname}}%
2672
\else%
2673
\pgfkeys{/tikzuml/usecase/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
2674
\fi%
2675
%\errmessage{TIKZUML ERROR : in umlusecase, invalid option \keyname}%
2676
}%
2677
}%
2678
\pgfkeys{/tikzuml/usecase/.cd, #1}%
2679
\pgfkeys{/tikzuml/usecase/.cd, x/.get=\tikzumlUseCaseX, y/.get=\tikzumlUseCaseY, width/.get=\tikzumlUseCaseTextWidth,%
2680
name/.get=\tikzumlUseCaseName,%
2681
draw/.get=\tikzumlUseCaseDrawColor, fill/.get=\tikzumlUseCaseFillColor,%
2682
text/.get=\tikzumlUseCaseTextColor%
2683
}%
2684
%
2685
\def\tikzumlUseCaseText{#2}%
2686
%
2687
\def\tikzumlUseCasePos{\tikzumlUseCaseX,\tikzumlUseCaseY}%
2688
%
2689
\ifthenelse{\equal{\tikzumlUseCaseTextWidth}{auto}}{%
2690
\iftikzumlusecaseWithoutCoords%
2691
\node[tikzuml usecase style, draw=\tikzumlUseCaseDrawColor, fill=\tikzumlUseCaseFillColor, text=\tikzumlUseCaseTextColor, font=\tikzumlDefaultFont, /tikzuml/usecase/style] (\tikzumlUseCaseName) {\tikzumlUseCaseText};%
2692
\else%
2693
\node[tikzuml usecase style, draw=\tikzumlUseCaseDrawColor, fill=\tikzumlUseCaseFillColor, text=\tikzumlUseCaseTextColor, font=\tikzumlDefaultFont, /tikzuml/usecase/style] (\tikzumlUseCaseName) at (\tikzumlUseCasePos) {\tikzumlUseCaseText};%
2694
\fi%
2695
}{%
2696
\iftikzumlusecaseWithoutCoords%
2697
\node[tikzuml usecase style, draw=\tikzumlUseCaseDrawColor, fill=\tikzumlUseCaseFillColor, text=\tikzumlUseCaseTextColor, font=\tikzumlDefaultFont, text width=\tikzumlUseCaseTextWidth, /tikzuml/usecase/style] (\tikzumlUseCaseName) {\tikzumlUseCaseText};%
2698
\else%
2699
\node[tikzuml usecase style, draw=\tikzumlUseCaseDrawColor, fill=\tikzumlUseCaseFillColor, text=\tikzumlUseCaseTextColor, font=\tikzumlDefaultFont, text width=\tikzumlUseCaseTextWidth, /tikzuml/usecase/style] (\tikzumlUseCaseName) at (\tikzumlUseCasePos) {\tikzumlUseCaseText};%
2700
\fi%
2701
}%
2702
%
2703
% add to fit
2704
\ifnum\c@tikzumlSystemLevel>0%
2705
\let\tikzumlSystemFitOld\tikzumlSystemFit%
2706
\xdef\tikzumlSystemFit{\tikzumlSystemFitOld (\tikzumlUseCaseName)}%
2707
\stepcounter{tikzumlSystemUseCaseNum}%
2708
\fi%
2709
}%
2710
%
2711
% define the actor symbol
2712
% optional : global tikzpicture styles
2713
\newcommand{\picturedactor}[1]{%
2714
\pgfkeys{/tikzuml/picactor/.cd, scale/.initial=1, .unknown/.code={}}%
2715
\pgfkeys{/tikzuml/picactor/.cd,#1}%
2716
\pgfkeys{/tikzuml/picactor/.cd, scale/.get=\tikzumlPicturedActorScale}%
2717
%
2718
\begin{tikzpicture}[#1]%
2719
\coordinate (head) at (0,4ex);%
2720
\coordinate (left-hand) at (-2ex,2ex);%
2721
\coordinate (right-hand) at (2ex,2ex);%
2722
\coordinate (left-foot) at (-2ex,-2ex);%
2723
\coordinate (right-foot) at (2ex,-2ex);%
2724
\coordinate (empty) at (0,-3ex);%
2725
\draw (empty) (0,0) -- (head);%
2726
\draw (left-hand) -- (right-hand);%
2727
\draw (0,0) -- (left-foot) (0,0) -- (right-foot);%
2728
\node[fill, draw, circle, inner sep=\tikzumlPicturedActorScale*0.3333ex, minimum size=\tikzumlPicturedActorScale*2ex, anchor=base] at (head) {};%
2729
\end{tikzpicture}%
2730
}%
2731
%
2732
% define an actor
2733
% arg : var name
2734
% optional : x, y: coordinates of the actor
2735
% scale: scale factor of the actor symbol
2736
% below: distance between the actor symbol and its name below
2737
% draw, text: colors
2738
% style: to manage every default TikZ option
2739
% no coords: to tell that the actor position is defined relatively
2740
% to another node (automatically used with TikZ options above, below, left, right, below left, ...)
2741
\newcommand{\umlactor}[2][]{%
2742
\stepcounter{tikzumlActorNum}%
2743
\pgfkeys{/tikzuml/actor/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, scale/.initial=1, below/.initial=\tikzumlActorDefaultBelow,%
2744
draw/.initial=\tikzumlDefaultDrawColor, text/.initial=\tikzumlDefaultTextColor,%
2745
style/.style={},%
2746
no coords/.is if=tikzumlactorWithoutCoords,%
2747
no coords=false,%
2748
.unknown/.code={%
2749
\let\keyname=\pgfkeyscurrentname%
2750
\let\keyvalue=\pgfkeyscurrentvalue%
2751
\ifthenelse{\equal{\keyname}{above}\OR%
2752
\equal{\keyname}{left}\OR%
2753
\equal{\keyname}{below}\OR%
2754
\equal{\keyname}{right}\OR%
2755
\equal{\keyname}{above left}\OR%
2756
\equal{\keyname}{above right}\OR%
2757
\equal{\keyname}{below left}\OR%
2758
\equal{\keyname}{below right}}{%
2759
\IfSubStr{\keyvalue}{ of }{%
2760
\pgfkeys{/tikzuml/actor/.cd, no coords}%
2761
}{}%
2762
}{}%
2763
\ifx\keyvalue\pgfkeysnovalue%
2764
\pgfkeys{/tikzuml/actor/.cd, style/.append style/.expand once={\keyname}}%
2765
\else%
2766
\pgfkeys{/tikzuml/actor/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
2767
\fi%
2768
%\errmessage{TIKZUML ERROR : in umlactor, invalid option \keyname}%
2769
}%
2770
}%
2771
\pgfkeys{/tikzuml/actor/.cd, #1}%
2772
\pgfkeys{/tikzuml/actor/.cd,%
2773
x/.get=\tikzumlActorX, y/.get=\tikzumlActorY, scale/.get=\tikzumlActorScale,%
2774
below/.get=\tikzumlActorBelow,%
2775
draw/.get=\tikzumlActorDrawColor, text/.get=\tikzumlActorTextColor}%
2776
%
2777
\def\tikzumlActorName{#2}%
2778
\begingroup%
2779
\def\_{_}\edef\x{\endgroup%
2780
\def\noexpand\tikzumlActorNodeName{\tikzumlActorName}}\x%
2781
%
2782
\def\tikzumlActorPos{\tikzumlActorX,\tikzumlActorY}%
2783
%
2784
\iftikzumlactorWithoutCoords%
2785
\node[tikzuml actor style, text=\tikzumlActorTextColor, font=\tikzumlDefaultFont, /tikzuml/actor/style] (\tikzumlActorNodeName) {\picturedactor{scale=\tikzumlActorScale, fill=white, draw=\tikzumlActorDrawColor, thick}};%
2786
\else%
2787
\node[tikzuml actor style, text=\tikzumlActorTextColor, font=\tikzumlDefaultFont, /tikzuml/actor/style] (\tikzumlActorNodeName) at (\tikzumlActorPos) {\picturedactor{scale=\tikzumlActorScale, fill=white, draw=\tikzumlActorDrawColor, thick}};%
2788
\fi%
2789
\node[text=\tikzumlActorTextColor, font=\tikzumlDefaultFont, below=\tikzumlActorScale*\tikzumlActorBelow] at (\tikzumlActorNodeName) {\tikzumlActorName};%
2790
%
2791
}%
2792
2793
% shortcuts for include and extend relation
2794
\newcommand{\umlinclude}[3][]{%
2795
\pgfkeys{/tikzuml/includerelation/.cd,%
2796
.unknown/.code={%
2797
\let\keyname=\pgfkeyscurrentname%
2798
\let\keyvalue=\pgfkeyscurrentvalue%
2799
\ifthenelse{\equal{\keyname}{stereo}}{%
2800
\errmessage{TIKZUML ERROR : in umlinclude, forbidden option stereo}%
2801
}{%
2802
\ifthenelse{\equal{\keyname}{geometry}}{%
2803
\errmessage{TIKZUML ERROR : in umlinclude, forbidden option geometry}%
2804
}{}%
2805
}%
2806
}}%
2807
\pgfkeys{/tikzuml/includerelation/.cd, #1}%
2808
\umlrelation[stereo=include, style={tikzuml dependency style}, #1]{#2}{#3}%
2809
}%
2810
\newcommand{\umlextend}[3][]{%
2811
\pgfkeys{/tikzuml/extendrelation/.cd,%
2812
.unknown/.code={%
2813
\let\keyname=\pgfkeyscurrentname%
2814
\let\keyvalue=\pgfkeyscurrentvalue%
2815
\ifthenelse{\equal{\keyname}{stereo}}{%
2816
\errmessage{TIKZUML ERROR : in umlextend, forbidden option stereo}%
2817
}{%
2818
\ifthenelse{\equal{\keyname}{geometry}}{%
2819
\errmessage{TIKZUML ERROR : in umlextend, forbidden option geometry}%
2820
}{}%
2821
}%
2822
}}%
2823
\pgfkeys{/tikzuml/extendrelation/.cd, #1}%
2824
\umlrelation[stereo=extend, style={tikzuml dependency style}, #1]{#2}{#3}%
2825
}%
2826
%
2827
\newcommand{\umlHVinclude}[3][]{%
2828
\pgfkeys{/tikzuml/includerelation/.cd,%
2829
.unknown/.code={%
2830
\let\keyname=\pgfkeyscurrentname%
2831
\let\keyvalue=\pgfkeyscurrentvalue%
2832
\ifthenelse{\equal{\keyname}{stereo}}{%
2833
\errmessage{TIKZUML ERROR : in umlHVinclude, forbidden option stereo}%
2834
}{%
2835
\ifthenelse{\equal{\keyname}{geometry}}{%
2836
\errmessage{TIKZUML ERROR : in umlHVinclude, forbidden option geometry}%
2837
}{}%
2838
}%
2839
}}%
2840
\pgfkeys{/tikzuml/includerelation/.cd, #1}%
2841
\umlrelation[geometry=-|, stereo=include, style={tikzuml dependency style}, #1]{#2}{#3}%
2842
}%
2843
\newcommand{\umlHVextend}[3][]{%
2844
\pgfkeys{/tikzuml/extendrelation/.cd,%
2845
.unknown/.code={%
2846
\let\keyname=\pgfkeyscurrentname%
2847
\let\keyvalue=\pgfkeyscurrentvalue%
2848
\ifthenelse{\equal{\keyname}{stereo}}{%
2849
\errmessage{TIKZUML ERROR : in umlHVextend, forbidden option stereo}%
2850
}{%
2851
\ifthenelse{\equal{\keyname}{geometry}}{%
2852
\errmessage{TIKZUML ERROR : in umlHVextend, forbidden option geometry}%
2853
}{}%
2854
}%
2855
}}%
2856
\pgfkeys{/tikzuml/extendrelation/.cd, #1}%
2857
\umlrelation[geometry=-|, stereo=extend, style={tikzuml dependency style}, #1]{#2}{#3}%
2858
}%
2859
%
2860
\newcommand{\umlVHinclude}[3][]{%
2861
\pgfkeys{/tikzuml/includerelation/.cd,%
2862
.unknown/.code={%
2863
\let\keyname=\pgfkeyscurrentname%
2864
\let\keyvalue=\pgfkeyscurrentvalue%
2865
\ifthenelse{\equal{\keyname}{stereo}}{%
2866
\errmessage{TIKZUML ERROR : in umlVHinclude, forbidden option stereo}%
2867
}{%
2868
\ifthenelse{\equal{\keyname}{geometry}}{%
2869
\errmessage{TIKZUML ERROR : in umlVHinclude, forbidden option geometry}%
2870
}{}%
2871
}%
2872
}}%
2873
\pgfkeys{/tikzuml/includerelation/.cd, #1}%
2874
\umlrelation[geometry=|-, stereo=include, style={tikzuml dependency style}, #1]{#2}{#3}%
2875
}%
2876
\newcommand{\umlVHextend}[3][]{%
2877
\pgfkeys{/tikzuml/extendrelation/.cd,%
2878
.unknown/.code={%
2879
\let\keyname=\pgfkeyscurrentname%
2880
\let\keyvalue=\pgfkeyscurrentvalue%
2881
\ifthenelse{\equal{\keyname}{stereo}}{%
2882
\errmessage{TIKZUML ERROR :in umlVHextend, forbidden option stereo}%
2883
}{%
2884
\ifthenelse{\equal{\keyname}{geometry}}{%
2885
\errmessage{TIKZUML ERROR : in umlVHextend, forbidden option geometry}%
2886
}{}%
2887
}%
2888
}}%
2889
\pgfkeys{/tikzuml/extendrelation/.cd, #1}%
2890
\umlrelation[geometry=|-, stereo=extend, style={tikzuml dependency style}, #1]{#2}{#3}%
2891
}%
2892
%
2893
\newcommand{\umlHVHinclude}[3][]{%
2894
\pgfkeys{/tikzuml/includerelation/.cd,%
2895
.unknown/.code={%
2896
\let\keyname=\pgfkeyscurrentname%
2897
\let\keyvalue=\pgfkeyscurrentvalue%
2898
\ifthenelse{\equal{\keyname}{stereo}}{%
2899
\errmessage{TIKZUML ERROR : in umlHVHinclude, forbidden option stereo}%
2900
}{%
2901
\ifthenelse{\equal{\keyname}{geometry}}{%
2902
\errmessage{TIKZUML ERROR : in umlHVHinclude, forbidden option geometry}%
2903
}{}%
2904
}%
2905
}}%
2906
\pgfkeys{/tikzuml/includerelation/.cd, #1}%
2907
\umlrelation[geometry=-|-, stereo=include, style={tikzuml dependency style}, #1]{#2}{#3}%
2908
}%
2909
\newcommand{\umlHVHextend}[3][]{%
2910
\pgfkeys{/tikzuml/extendrelation/.cd,%
2911
.unknown/.code={%
2912
\let\keyname=\pgfkeyscurrentname%
2913
\let\keyvalue=\pgfkeyscurrentvalue%
2914
\ifthenelse{\equal{\keyname}{stereo}}{%
2915
\errmessage{TIKZUML ERROR : in umlHVHextend, forbidden option stereo}%
2916
}{%
2917
\ifthenelse{\equal{\keyname}{geometry}}{%
2918
\errmessage{TIKZUML ERROR : in umlHVHextend, forbidden option geometry}%
2919
}{}%
2920
}%
2921
}}%
2922
\pgfkeys{/tikzuml/extendrelation/.cd, #1}%
2923
\umlrelation[geometry=-|-, stereo=extend, style={tikzuml dependency style}, #1]{#2}{#3}%
2924
}%
2925
%
2926
\newcommand{\umlVHVinclude}[3][]{%
2927
\pgfkeys{/tikzuml/includerelation/.cd,%
2928
.unknown/.code={%
2929
\let\keyname=\pgfkeyscurrentname%
2930
\let\keyvalue=\pgfkeyscurrentvalue%
2931
\ifthenelse{\equal{\keyname}{stereo}}{%
2932
\errmessage{TIKZUML ERROR : in umlVHVinclude, forbidden option stereo}%
2933
}{%
2934
\ifthenelse{\equal{\keyname}{geometry}}{%
2935
\errmessage{TIKZUML ERROR : in umlVHVinclude, forbidden option geometry}%
2936
}{}%
2937
}%
2938
}}%
2939
\pgfkeys{/tikzuml/includerelation/.cd, #1}%
2940
\umlrelation[geometry=|-|, stereo=include, style={tikzuml dependency style}, #1]{#2}{#3}%
2941
}%
2942
\newcommand{\umlVHVextend}[3][]{%
2943
\pgfkeys{/tikzuml/extendrelation/.cd,%
2944
.unknown/.code={%
2945
\let\keyname=\pgfkeyscurrentname%
2946
\let\keyvalue=\pgfkeyscurrentvalue%
2947
\ifthenelse{\equal{\keyname}{stereo}}{%
2948
\errmessage{TIKZUML ERROR : in umlVHVextend, forbidden option stereo}%
2949
}{%
2950
\ifthenelse{\equal{\keyname}{geometry}}{%
2951
\errmessage{TIKZUML ERROR : in umlVHVextend, forbidden option geometry}%
2952
}{}%
2953
}%
2954
}}%
2955
\pgfkeys{/tikzuml/extendrelation/.cd, #1}%
2956
\umlrelation[geometry=|-|, stereo=extend, style={tikzuml dependency style}, #1]{#2}{#3}%
2957
}%
2958
%
2959
\newcommand{\umlCNinclude}[4][]{%
2960
\pgfkeys{/tikzuml/includerelation/.cd,%
2961
.unknown/.code={%
2962
\let\keyname=\pgfkeyscurrentname%
2963
\let\keyvalue=\pgfkeyscurrentvalue%
2964
\ifthenelse{\equal{\keyname}{stereo}}{%
2965
\errmessage{TIKZUML ERROR : in umlCNinclude, forbidden option stereo}%
2966
}{}%
2967
}}%
2968
\pgfkeys{/tikzuml/includerelation/.cd, #1}%
2969
\umlCNrelation[stereo=include, style={tikzuml dependency style}, #1]{#2}{#3}{#4}%
2970
}%
2971
\newcommand{\umlCNextend}[4][]{%
2972
\pgfkeys{/tikzuml/extendrelation/.cd,%
2973
.unknown/.code={%
2974
\let\keyname=\pgfkeyscurrentname%
2975
\let\keyvalue=\pgfkeyscurrentvalue%
2976
\ifthenelse{\equal{\keyname}{stereo}}{%
2977
\errmessage{TIKZUML ERROR : in umlCNextend, forbidden option stereo}%
2978
}{}%
2979
}}%
2980
\pgfkeys{/tikzuml/extendrelation/.cd, #1}%
2981
\umlCNrelation[stereo=extend, style={tikzuml dependency style}, #1]{#2}{#3}{#4}%
2982
}%
2983
%
2984
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2985
% state diagrams %
2986
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2987
%
2988
\tikzstyle{tikzuml state style}=[rectangle split, rectangle split parts=2, rounded corners, inner xsep=1.5ex]%
2989
\tikzstyle{tikzuml transition style}=[color=\tikzumlDefaultDrawColor, rounded corners, -angle 45]%
2990
%
2991
\newcounter{tikzumlStateJoinNum}%
2992
\newcounter{tikzumlStateDecisionNum}%
2993
\newcounter{tikzumlStateInitialNum}%
2994
\newcounter{tikzumlStateFinalNum}%
2995
\newcounter{tikzumlStateEnterNum}%
2996
\newcounter{tikzumlStateExitNum}%
2997
\newcounter{tikzumlStateEndNum}%
2998
\newcounter{tikzumlStateHistoryNum}%
2999
\newcounter{tikzumlStateDeepHistoryNum}%
3000
\newcounter{tikzumlStateLevel}%
3001
\newcounter{tikzumlStateSubStateNum}%
3002
\newcounter{tikzumlStateText}%
3003
%
3004
\newif\iftikzumlstatejoinWithoutCoords%
3005
\newif\iftikzumlstatedecisionWithoutCoords%
3006
\newif\iftikzumlstateinitialWithoutCoords%
3007
\newif\iftikzumlstatefinalWithoutCoords%
3008
\newif\iftikzumlstateenterWithoutCoords%
3009
\newif\iftikzumlstateexitWithoutCoords%
3010
\newif\iftikzumlstateendWithoutCoords%
3011
\newif\iftikzumlstatehistoryWithoutCoords%
3012
\newif\iftikzumlstatedeephistoryWithoutCoords%
3013
\newif\iftikzumlstateWithoutCoords%
3014
%
3015
% define a uml join state
3016
% args : name of the state
3017
% optional : x,y: coordinates of the state
3018
% width: width of the state node
3019
% name: name of the state node
3020
% color: color of the join symbol
3021
% style: to manage every default TikZ option
3022
% no coords: to tell that the state position is defined relatively
3023
% to another node (automatically used with TikZ options above, below, left, right, below left, ...)
3024
\newcommand{\umlstatejoin}[1][]{%
3025
\pgfkeys{/tikzuml/statejoin/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlStateJoinDefaultWidth,%
3026
name/.initial=statejoin-\thetikzumlStateJoinNum,%
3027
color/.initial=\tikzumlDefaultDrawColor, style/.style={},%
3028
no coords/.is if=tikzumlstatejoinWithoutCoords,%
3029
no coords=false,%
3030
.unknown/.code={%
3031
\let\keyname=\pgfkeyscurrentname%
3032
\let\keyvalue=\pgfkeyscurrentvalue%
3033
\ifthenelse{\equal{\keyname}{above}\OR%
3034
\equal{\keyname}{left}\OR%
3035
\equal{\keyname}{below}\OR%
3036
\equal{\keyname}{right}\OR%
3037
\equal{\keyname}{above left}\OR%
3038
\equal{\keyname}{above right}\OR%
3039
\equal{\keyname}{below left}\OR%
3040
\equal{\keyname}{below right}}{%
3041
\IfSubStr{\keyvalue}{ of }{%
3042
\pgfkeys{/tikzuml/statejoin/.cd, no coords}%
3043
}{}%
3044
}{}%
3045
\ifx\keyvalue\pgfkeysnovalue%
3046
\pgfkeys{/tikzuml/statejoin/.cd, style/.append style/.expand once={\keyname}}%
3047
\else%
3048
\pgfkeys{/tikzuml/statejoin/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
3049
\fi%
3050
%\errmessage{TIKZUML ERROR : in umlstatejoin, invalid option \keyname}%
3051
}%
3052
}%
3053
\pgfkeys{/tikzuml/statejoin/.cd, #1}%
3054
\pgfkeys{/tikzuml/statejoin/.cd, x/.get=\tikzumlStateJoinX, y/.get=\tikzumlStateJoinY, width/.get=\tikzumlStateJoinMinimumWidth,%
3055
name/.get=\tikzumlStateJoinName, color/.get=\tikzumlStateJoinColor%
3056
}%
3057
%
3058
\def\tikzumlStateJoinPos{\tikzumlStateJoinX,\tikzumlStateJoinY}%
3059
%
3060
\iftikzumlstatejoinWithoutCoords%
3061
\node[circle, minimum size=\tikzumlStateJoinMinimumWidth, draw=\tikzumlStateJoinColor, fill=\tikzumlStateJoinColor, /tikzuml/statejoin/style] (\tikzumlStateJoinName) {};%
3062
\else%
3063
\node[circle, minimum size=\tikzumlStateJoinMinimumWidth, draw=\tikzumlStateJoinColor, fill=\tikzumlStateJoinColor, /tikzuml/statejoin/style] (\tikzumlStateJoinName) at (\tikzumlStateJoinPos) {};%
3064
\fi%
3065
%
3066
% add to fit
3067
\ifnum\c@tikzumlStateLevel>0%
3068
\edef\tikzumlStateFitOld{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
3069
\expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitOld (\tikzumlStateJoinName)}%
3070
\stepcounter{tikzumlStateSubStateNum}%
3071
\fi%
3072
\stepcounter{tikzumlStateJoinNum}%
3073
}%
3074
%
3075
% define a uml decision state
3076
% args : name of the state
3077
% optional : x,y: coordinates of the state
3078
% width: width of the state node
3079
% name: name of the state node
3080
% color: color of the join symbol
3081
% style: to manage every default TikZ option
3082
% no coords: to tell that the state position is defined relatively
3083
% to another node (automatically used with TikZ options above, below, left, right, below left, ...)
3084
\newcommand{\umlstatedecision}[1][]{%
3085
\pgfkeys{/tikzuml/statedecision/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlStateDecisionDefaultWidth,%
3086
name/.initial=statedecision-\thetikzumlStateDecisionNum,%
3087
color/.initial=\tikzumlDefaultDrawColor, style/.style={},%
3088
no coords/.is if=tikzumlstatedecisionWithoutCoords,%
3089
no coords=false,%
3090
.unknown/.code={%
3091
\let\keyname=\pgfkeyscurrentname%
3092
\let\keyvalue=\pgfkeyscurrentvalue%
3093
\ifthenelse{\equal{\keyname}{above}\OR%
3094
\equal{\keyname}{left}\OR%
3095
\equal{\keyname}{below}\OR%
3096
\equal{\keyname}{right}\OR%
3097
\equal{\keyname}{above left}\OR%
3098
\equal{\keyname}{above right}\OR%
3099
\equal{\keyname}{below left}\OR%
3100
\equal{\keyname}{below right}}{%
3101
\IfSubStr{\keyvalue}{ of }{%
3102
\pgfkeys{/tikzuml/statedecision/.cd, no coords}%
3103
}{}%
3104
}{}%
3105
\ifx\keyvalue\pgfkeysnovalue%
3106
\pgfkeys{/tikzuml/statedecision/.cd, style/.append style/.expand once={\keyname}}%
3107
\else%
3108
\pgfkeys{/tikzuml/statedecision/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
3109
\fi%
3110
%\errmessage{TIKZUML ERROR : in umlstatedecision, invalid option \keyname}%
3111
}%
3112
}%
3113
\pgfkeys{/tikzuml/statedecision/.cd, #1}%
3114
\pgfkeys{/tikzuml/statedecision/.cd, x/.get=\tikzumlStateDecisionX, y/.get=\tikzumlStateDecisionY, width/.get=\tikzumlStateDecisionMinimumWidth,%
3115
name/.get=\tikzumlStateDecisionName, color/.get=\tikzumlStateDecisionColor%
3116
}%
3117
%
3118
\def\tikzumlStateDecisionPos{\tikzumlStateDecisionX,\tikzumlStateDecisionY}%
3119
%
3120
\iftikzumlstatedecisionWithoutCoords%
3121
\node[rectangle, rotate=45, minimum size=\tikzumlStateDecisionMinimumWidth, draw=\tikzumlStateDecisionColor, /tikzuml/statedecision/style] (\tikzumlStateDecisionName) {};%
3122
\else%
3123
\node[rectangle, rotate=45, minimum size=\tikzumlStateDecisionMinimumWidth, draw=\tikzumlStateDecisionColor, /tikzuml/statedecision/style] (\tikzumlStateDecisionName) at (\tikzumlStateDecisionPos) {};%
3124
\fi%
3125
%
3126
% add to fit
3127
\ifnum\c@tikzumlStateLevel>0%
3128
\edef\tikzumlStateFitOld{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
3129
\expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitOld (\tikzumlStateDecisionName)}%
3130
\stepcounter{tikzumlStateSubStateNum}%
3131
\fi%
3132
\stepcounter{tikzumlStateDecisionNum}%
3133
}%
3134
%
3135
% define a uml initial state
3136
% args : name of the state
3137
% optional : x,y: coordinates of the state
3138
% width: width of the state node
3139
% name: name of the state node
3140
% entry, do, exit: entry/do/exit action of the state
3141
% color: color of the join symbol
3142
% style: to manage every default TikZ option
3143
% no coords: to tell that the state position is defined relatively
3144
% to another node (automatically used with TikZ options above, below, left, right, below left, ...)
3145
\newcommand{\umlstateinitial}[1][]{%
3146
\pgfkeys{/tikzuml/stateinitial/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlStateInitialDefaultWidth,%
3147
name/.initial=stateinitial-\thetikzumlStateInitialNum,%
3148
color/.initial=\tikzumlDefaultDrawColor, style/.style={},%
3149
no coords/.is if=tikzumlstateinitialWithoutCoords,%
3150
no coords=false,%
3151
.unknown/.code={%
3152
\let\keyname=\pgfkeyscurrentname%
3153
\let\keyvalue=\pgfkeyscurrentvalue%
3154
\ifthenelse{\equal{\keyname}{above}\OR%
3155
\equal{\keyname}{left}\OR%
3156
\equal{\keyname}{below}\OR%
3157
\equal{\keyname}{right}\OR%
3158
\equal{\keyname}{above left}\OR%
3159
\equal{\keyname}{above right}\OR%
3160
\equal{\keyname}{below left}\OR%
3161
\equal{\keyname}{below right}}{%
3162
\IfSubStr{\keyvalue}{ of }{%
3163
\pgfkeys{/tikzuml/stateinitial/.cd, no coords}%
3164
}{}%
3165
}{}%
3166
\ifx\keyvalue\pgfkeysnovalue%
3167
\pgfkeys{/tikzuml/stateinitial/.cd, style/.append style/.expand once={\keyname}}%
3168
\else%
3169
\pgfkeys{/tikzuml/stateinitial/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
3170
\fi%
3171
%\errmessage{TIKZUML ERROR : in umlstateinitial, invalid option \keyname}%
3172
}%
3173
}%
3174
\pgfkeys{/tikzuml/stateinitial/.cd, #1}%
3175
\pgfkeys{/tikzuml/stateinitial/.cd, x/.get=\tikzumlStateInitialX, y/.get=\tikzumlStateInitialY, width/.get=\tikzumlStateInitialMinimumWidth,%
3176
name/.get=\tikzumlStateInitialName, color/.get=\tikzumlStateInitialColor%
3177
}%
3178
%
3179
\def\tikzumlStateInitialPos{\tikzumlStateInitialX,\tikzumlStateInitialY}%
3180
%
3181
\iftikzumlstateinitialWithoutCoords%
3182
\node[circle, minimum size=\tikzumlStateInitialMinimumWidth, fill=\tikzumlStateInitialColor, /tikzuml/stateinitial/style] (\tikzumlStateInitialName) {};%
3183
\else%
3184
\node[circle, minimum size=\tikzumlStateInitialMinimumWidth, fill=\tikzumlStateInitialColor, /tikzuml/stateinitial/style] (\tikzumlStateInitialName) at (\tikzumlStateInitialPos) {};%
3185
\fi%
3186
%
3187
% add to fit
3188
\ifnum\c@tikzumlStateLevel>0%
3189
\edef\tikzumlStateFitOld{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
3190
\expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitOld (\tikzumlStateInitialName)}%
3191
\stepcounter{tikzumlStateSubStateNum}%
3192
\fi%
3193
\stepcounter{tikzumlStateInitialNum}%
3194
}%
3195
%
3196
% define a uml final state
3197
% args : name of the state
3198
% optional : x,y: coordinates of the state
3199
% width: width of the state node
3200
% name: name of the state node
3201
% color: color of the join symbol
3202
% style: to manage every default TikZ option
3203
% no coords: to tell that the state position is defined relatively
3204
% to another node (automatically used with TikZ options above, below, left, right, below left, ...)
3205
\newcommand{\umlstatefinal}[1][]{%
3206
\pgfkeys{/tikzuml/statefinal/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlStateFinalDefaultWidth,%
3207
name/.initial=statefinal-\thetikzumlStateFinalNum,%
3208
color/.initial=\tikzumlDefaultDrawColor, style/.style={},%
3209
no coords/.is if=tikzumlstatefinalWithoutCoords,%
3210
no coords=false,%
3211
.unknown/.code={%
3212
\let\keyname=\pgfkeyscurrentname%
3213
\let\keyvalue=\pgfkeyscurrentvalue%
3214
\ifthenelse{\equal{\keyname}{above}\OR%
3215
\equal{\keyname}{left}\OR%
3216
\equal{\keyname}{below}\OR%
3217
\equal{\keyname}{right}\OR%
3218
\equal{\keyname}{above left}\OR%
3219
\equal{\keyname}{above right}\OR%
3220
\equal{\keyname}{below left}\OR%
3221
\equal{\keyname}{below right}}{%
3222
\IfSubStr{\keyvalue}{ of }{%
3223
\pgfkeys{/tikzuml/statefinal/.cd, no coords}%
3224
}{}%
3225
}{}%
3226
\ifx\keyvalue\pgfkeysnovalue%
3227
\pgfkeys{/tikzuml/statefinal/.cd, style/.append style/.expand once={\keyname}}%
3228
\else%
3229
\pgfkeys{/tikzuml/statefinal/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
3230
\fi%
3231
%\errmessage{TIKZUML ERROR : in umlstatefinal, invalid option \keyname}%
3232
}%
3233
}%
3234
\pgfkeys{/tikzuml/statefinal/.cd, #1}%
3235
\pgfkeys{/tikzuml/statefinal/.cd, x/.get=\tikzumlStateFinalX, y/.get=\tikzumlStateFinalY, width/.get=\tikzumlStateFinalMinimumWidth,%
3236
name/.get=\tikzumlStateFinalName, color/.get=\tikzumlStateFinalColor%
3237
}%
3238
%
3239
\def\tikzumlStateFinalPos{\tikzumlStateFinalX,\tikzumlStateFinalY}%
3240
%
3241
\iftikzumlstatefinalWithoutCoords%
3242
\node[circle, minimum size=\tikzumlStateFinalMinimumWidth, draw=\tikzumlStateFinalColor, fill=\tikzumlStateFinalColor, double, double distance=0.1cm, /tikzuml/statefinal/style] (\tikzumlStateFinalName) {};%
3243
\else%
3244
\node[circle, minimum size=\tikzumlStateFinalMinimumWidth, draw=\tikzumlStateFinalColor, fill=\tikzumlStateFinalColor, double, double distance=0.1cm, /tikzuml/statefinal/style] (\tikzumlStateFinalName) at (\tikzumlStateFinalPos) {};%
3245
\fi%
3246
%
3247
% add to fit
3248
\ifnum\c@tikzumlStateLevel>0%
3249
\edef\tikzumlStateFitOld{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
3250
\expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitOld (\tikzumlStateFinalName)}%
3251
\stepcounter{tikzumlStateSubStateNum}%
3252
\fi%
3253
\stepcounter{tikzumlStateFinalNum}%
3254
}%
3255
%
3256
% define a uml enter state
3257
% args : name of the state
3258
% optional : x,y: coordinates of the state
3259
% width: width of the state node
3260
% name: name of the state node
3261
% color: color of the join symbol
3262
% style: to manage every default TikZ option
3263
% no coords: to tell that the state position is defined relatively
3264
% to another node (automatically used with TikZ options above, below, left, right, below left, ...)
3265
\newcommand{\umlstateenter}[1][]{%
3266
\pgfkeys{/tikzuml/stateenter/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlStateEnterDefaultWidth,%
3267
name/.initial=stateenter-\thetikzumlStateEnterNum,%
3268
color/.initial=\tikzumlDefaultDrawColor, style/.style={},%
3269
no coords/.is if=tikzumlstateenterWithoutCoords,%
3270
no coords=false,%
3271
.unknown/.code={%
3272
\let\keyname=\pgfkeyscurrentname%
3273
\let\keyvalue=\pgfkeyscurrentvalue%
3274
\ifthenelse{\equal{\keyname}{above}\OR%
3275
\equal{\keyname}{left}\OR%
3276
\equal{\keyname}{below}\OR%
3277
\equal{\keyname}{right}\OR%
3278
\equal{\keyname}{above left}\OR%
3279
\equal{\keyname}{above right}\OR%
3280
\equal{\keyname}{below left}\OR%
3281
\equal{\keyname}{below right}}{%
3282
\IfSubStr{\keyvalue}{ of }{%
3283
\pgfkeys{/tikzuml/stateenter/.cd, no coords}%
3284
}{}%
3285
}{}%
3286
\ifx\keyvalue\pgfkeysnovalue%
3287
\pgfkeys{/tikzuml/stateenter/.cd, style/.append style/.expand once={\keyname}}%
3288
\else%
3289
\pgfkeys{/tikzuml/stateenter/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
3290
\fi%
3291
%\errmessage{TIKZUML ERROR : in umlstateenter, invalid option \keyname}%
3292
}%
3293
}%
3294
\pgfkeys{/tikzuml/stateenter/.cd, #1}%
3295
\pgfkeys{/tikzuml/stateenter/.cd, x/.get=\tikzumlStateEnterX, y/.get=\tikzumlStateEnterY, width/.get=\tikzumlStateEnterMinimumWidth,%
3296
name/.get=\tikzumlStateEnterName, color/.get=\tikzumlStateEnterColor%
3297
}%
3298
%
3299
\def\tikzumlStateEnterPos{\tikzumlStateEnterX,\tikzumlStateEnterY}%
3300
%
3301
\iftikzumlstateenterWithoutCoords%
3302
\node[circle, minimum size=\tikzumlStateEnterMinimumWidth, draw=\tikzumlStateEnterColor, /tikzuml/stateenter/style] (\tikzumlStateEnterName) {};%
3303
\else%
3304
\node[circle, minimum size=\tikzumlStateEnterMinimumWidth, draw=\tikzumlStateEnterColor, /tikzuml/stateenter/style] (\tikzumlStateEnterName) at (\tikzumlStateEnterPos) {};%
3305
\fi%
3306
%
3307
% add to fit
3308
\ifnum\c@tikzumlStateLevel>0%
3309
\edef\tikzumlStateFitOld{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
3310
\expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitOld (\tikzumlStateEnterName)}%
3311
\stepcounter{tikzumlStateSubStateNum}%
3312
\fi%
3313
\stepcounter{tikzumlStateEnterNum}%
3314
}%
3315
%
3316
% define a uml exit state
3317
% args : name of the state
3318
% optional : x,y: coordinates of the state
3319
% width: width of the state node
3320
% name: name of the state node
3321
% color: color of the join symbol
3322
% style: to manage every default TikZ option
3323
% no coords: to tell that the state position is defined relatively
3324
% to another node (automatically used with TikZ options above, below, left, right, below left, ...)
3325
\newcommand{\umlstateexit}[1][]{%
3326
\pgfkeys{/tikzuml/stateexit/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlStateExitDefaultWidth,%
3327
name/.initial=stateexit-\thetikzumlStateExitNum,%
3328
color/.initial=\tikzumlDefaultDrawColor, style/.style={},%
3329
no coords/.is if=tikzumlstateexitWithoutCoords,%
3330
no coords=false,%
3331
.unknown/.code={%
3332
\let\keyname=\pgfkeyscurrentname%
3333
\let\keyvalue=\pgfkeyscurrentvalue%
3334
\ifthenelse{\equal{\keyname}{above}\OR%
3335
\equal{\keyname}{left}\OR%
3336
\equal{\keyname}{below}\OR%
3337
\equal{\keyname}{right}\OR%
3338
\equal{\keyname}{above left}\OR%
3339
\equal{\keyname}{above right}\OR%
3340
\equal{\keyname}{below left}\OR%
3341
\equal{\keyname}{below right}}{%
3342
\IfSubStr{\keyvalue}{ of }{%
3343
\pgfkeys{/tikzuml/stateexit/.cd, no coords}%
3344
}{}%
3345
}{}%
3346
\ifx\keyvalue\pgfkeysnovalue%
3347
\pgfkeys{/tikzuml/stateexit/.cd, style/.append style/.expand once={\keyname}}%
3348
\else%
3349
\pgfkeys{/tikzuml/stateexit/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
3350
\fi%
3351
%\errmessage{TIKZUML ERROR : in umlstateexit, invalid option \keyname}%
3352
}%
3353
}%
3354
\pgfkeys{/tikzuml/stateexit/.cd, #1}%
3355
\pgfkeys{/tikzuml/stateexit/.cd, x/.get=\tikzumlStateExitX, y/.get=\tikzumlStateExitY, width/.get=\tikzumlStateExitMinimumWidth,%
3356
name/.get=\tikzumlStateExitName, color/.get=\tikzumlStateExitColor%
3357
}%
3358
%
3359
\def\tikzumlStateExitPos{\tikzumlStateExitX,\tikzumlStateExitY}%
3360
%
3361
\iftikzumlstateexitWithoutCoords%
3362
\node[circle, minimum size=\tikzumlStateExitMinimumWidth, draw=\tikzumlStateExitColor, /tikzuml/stateexit/style] (\tikzumlStateExitName) {};%
3363
\else%
3364
\node[circle, minimum size=\tikzumlStateExitMinimumWidth, draw=\tikzumlStateExitColor, /tikzuml/stateexit/style] (\tikzumlStateExitName) at (\tikzumlStateExitPos) {};%
3365
\fi%
3366
\draw[draw=\tikzumlStateExitColor] (\tikzumlStateExitName.north east) -- (\tikzumlStateExitName.south west) (\tikzumlStateExitName.north west) -- (\tikzumlStateExitName.south east);
3367
%
3368
% add to fit
3369
\ifnum\c@tikzumlStateLevel>0%
3370
\edef\tikzumlStateFitOld{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
3371
\expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitOld (\tikzumlStateExitName)}%
3372
\stepcounter{tikzumlStateSubStateNum}%
3373
\fi%
3374
\stepcounter{tikzumlStateExitNum}%
3375
}%
3376
%
3377
% define a uml end state
3378
% args : name of the state
3379
% optional : x,y: coordinates of the state
3380
% width: width of the state node
3381
% name: name of the state node
3382
% color: color of the join symbol
3383
% style: to manage every default TikZ option
3384
% no coords: to tell that the state position is defined relatively
3385
% to another node (automatically used with TikZ options above, below, left, right, below left, ...)
3386
\newcommand{\umlstateend}[1][]{%
3387
\pgfkeys{/tikzuml/stateend/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlStateEndDefaultWidth,%
3388
name/.initial=stateend-\thetikzumlStateEndNum,%
3389
color/.initial=\tikzumlDefaultDrawColor, style/.style={},%
3390
no coords/.is if=tikzumlstateendWithoutCoords,%
3391
no coords=false,%
3392
.unknown/.code={%
3393
\let\keyname=\pgfkeyscurrentname%
3394
\let\keyvalue=\pgfkeyscurrentvalue%
3395
\ifthenelse{\equal{\keyname}{above}\OR%
3396
\equal{\keyname}{left}\OR%
3397
\equal{\keyname}{below}\OR%
3398
\equal{\keyname}{right}\OR%
3399
\equal{\keyname}{above left}\OR%
3400
\equal{\keyname}{above right}\OR%
3401
\equal{\keyname}{below left}\OR%
3402
\equal{\keyname}{below right}}{%
3403
\IfSubStr{\keyvalue}{ of }{%
3404
\pgfkeys{/tikzuml/stateend/.cd, no coords}%
3405
}{}%
3406
}{}%
3407
\ifx\keyvalue\pgfkeysnovalue%
3408
\pgfkeys{/tikzuml/stateend/.cd, style/.append style/.expand once={\keyname}}%
3409
\else%
3410
\pgfkeys{/tikzuml/stateend/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
3411
\fi%
3412
%\errmessage{TIKZUML ERROR : in umlstateend, invalid option \keyname}%
3413
}%
3414
}%
3415
\pgfkeys{/tikzuml/stateend/.cd, #1}%
3416
\pgfkeys{/tikzuml/stateend/.cd, x/.get=\tikzumlStateEndX, y/.get=\tikzumlStateEndY, width/.get=\tikzumlStateEndMinimumWidth,%
3417
name/.get=\tikzumlStateEndName, color/.get=\tikzumlStateEndColor%
3418
}%
3419
%
3420
\def\tikzumlStateEndPos{\tikzumlStateEndX,\tikzumlStateEndY}%
3421
%
3422
\iftikzumlstateendWithoutCoords%
3423
\node[circle, minimum size=\tikzumlStateEndMinimumWidth, /tikzuml/stateend/style] (\tikzumlStateEndName) {};%
3424
\else%
3425
\node[circle, minimum size=\tikzumlStateEndMinimumWidth, /tikzuml/stateend/style] (\tikzumlStateEndName) at (\tikzumlStateEndPos) {};%
3426
\fi%
3427
\draw[draw=\tikzumlStateEndColor] (\tikzumlStateEndName.north east) -- (\tikzumlStateEndName.south west) (\tikzumlStateEndName.north west) -- (\tikzumlStateEndName.south east);
3428
%
3429
% add to fit
3430
\ifnum\c@tikzumlStateLevel>0%
3431
\edef\tikzumlStateFitOld{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
3432
\expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitOld (\tikzumlStateEndName)}%
3433
\stepcounter{tikzumlStateSubStateNum}%
3434
\fi%
3435
\stepcounter{tikzumlStateEndNum}%
3436
}%
3437
%
3438
\newcommand{\picturedhistory}[1]{%
3439
\begin{tikzpicture}[#1]%
3440
\draw[thick] (-0.1cm,-0.15cm) -- (-0.1cm,0.15cm)
3441
(-0.1cm,0) -- (0.1cm,0)
3442
(0.1cm,-0.15cm) -- (0.1cm,0.15cm);%
3443
\end{tikzpicture}%
3444
}%
3445
%
3446
% define a uml history state
3447
% args : name of the state
3448
% optional : x,y: coordinates of the state
3449
% width: width of the state node
3450
% name: name of the state node
3451
% color: color of the join symbol
3452
% style: to manage every default TikZ option
3453
% no coords: to tell that the state position is defined relatively
3454
% to another node (automatically used with TikZ options above, below, left, right, below left, ...)
3455
\newcommand{\umlstatehistory}[1][]{%
3456
\pgfkeys{/tikzuml/statehistory/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlStateHistoryDefaultWidth,%
3457
name/.initial=statehistory-\thetikzumlStateHistoryNum,%
3458
color/.initial=\tikzumlDefaultDrawColor, style/.style={},%
3459
no coords/.is if=tikzumlstatehistoryWithoutCoords,%
3460
no coords=false,%
3461
.unknown/.code={%
3462
\let\keyname=\pgfkeyscurrentname%
3463
\let\keyvalue=\pgfkeyscurrentvalue%
3464
\ifthenelse{\equal{\keyname}{above}\OR%
3465
\equal{\keyname}{left}\OR%
3466
\equal{\keyname}{below}\OR%
3467
\equal{\keyname}{right}\OR%
3468
\equal{\keyname}{above left}\OR%
3469
\equal{\keyname}{above right}\OR%
3470
\equal{\keyname}{below left}\OR%
3471
\equal{\keyname}{below right}}{%
3472
\IfSubStr{\keyvalue}{ of }{%
3473
\pgfkeys{/tikzuml/statehistory/.cd, no coords}%
3474
}{}%
3475
}{}%
3476
\ifx\keyvalue\pgfkeysnovalue%
3477
\pgfkeys{/tikzuml/statehistory/.cd, style/.append style/.expand once={\keyname}}%
3478
\else%
3479
\pgfkeys{/tikzuml/statehistory/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
3480
\fi%
3481
%\errmessage{TIKZUML ERROR : in umlstatehistory, invalid option \keyname}%
3482
}%
3483
}%
3484
\pgfkeys{/tikzuml/statehistory/.cd, #1}%
3485
\pgfkeys{/tikzuml/statehistory/.cd, x/.get=\tikzumlStateHistoryX, y/.get=\tikzumlStateHistoryY, width/.get=\tikzumlStateHistoryMinimumWidth,%
3486
name/.get=\tikzumlStateHistoryName, color/.get=\tikzumlStateHistoryColor%
3487
}%
3488
%
3489
\def\tikzumlStateHistoryPos{\tikzumlStateHistoryX,\tikzumlStateHistoryY}%
3490
%
3491
\iftikzumlstatehistoryWithoutCoords%
3492
\node[circle, minimum size=\tikzumlStateHistoryMinimumWidth, draw=\tikzumlStateHistoryColor, /tikzuml/statehistory/style] (\tikzumlStateHistoryName) {\picturedhistory{draw=\tikzumlStateHistoryColor}};%
3493
\else%
3494
\node[circle, minimum size=\tikzumlStateHistoryMinimumWidth, draw=\tikzumlStateHistoryColor, /tikzuml/statehistory/style] (\tikzumlStateHistoryName) at (\tikzumlStateHistoryPos) {\picturedhistory{draw=\tikzumlStateHistoryColor}};%
3495
\fi%
3496
%
3497
% add to fit
3498
\ifnum\c@tikzumlStateLevel>0%
3499
\edef\tikzumlStateFitOld{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
3500
\expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitOld (\tikzumlStateHistoryName)}%
3501
\stepcounter{tikzumlStateSubStateNum}%
3502
\fi%
3503
\stepcounter{tikzumlStateHistoryNum}%
3504
}%
3505
%
3506
\newcommand{\pictureddeephistory}[1]{%
3507
\begin{tikzpicture}[#1]%
3508
\draw[thick] (-0.1cm,-0.15cm) -- (-0.1cm,0.15cm)
3509
(-0.1cm,0) -- (0.1cm,0)
3510
(0.1cm,-0.15cm) -- (0.1cm,0.15cm)
3511
(0.23cm,0.19cm) -- (0.23cm,0.11cm)
3512
(0.20cm,0.17cm) -- (0.26cm,0.13cm)
3513
(0.20cm,0.13cm) -- (0.26cm,0.17cm);%
3514
\end{tikzpicture}%
3515
}%
3516
%
3517
% define a uml deep-history state
3518
% args : name of the state
3519
% optional : x,y: coordinates of the state
3520
% width: width of the state node
3521
% name: name of the state node
3522
% color: color of the join symbol
3523
% style: to manage every default TikZ option
3524
% no coords: to tell that the state position is defined relatively
3525
% to another node (automatically used with TikZ options above, below, left, right, below left, ...)
3526
\newcommand{\umlstatedeephistory}[1][]{%
3527
\pgfkeys{/tikzuml/statedeephistory/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlStateDeepHistoryDefaultWidth,%
3528
name/.initial=statedeephistory-\thetikzumlStateDeepHistoryNum,%
3529
color/.initial=\tikzumlDefaultDrawColor, style/.style={},%
3530
no coords/.is if=tikzumlstatedeephistoryWithoutCoords,%
3531
no coords=false,%
3532
.unknown/.code={%
3533
\let\keyname=\pgfkeyscurrentname%
3534
\let\keyvalue=\pgfkeyscurrentvalue%
3535
\ifthenelse{\equal{\keyname}{above}\OR%
3536
\equal{\keyname}{left}\OR%
3537
\equal{\keyname}{below}\OR%
3538
\equal{\keyname}{right}\OR%
3539
\equal{\keyname}{above left}\OR%
3540
\equal{\keyname}{above right}\OR%
3541
\equal{\keyname}{below left}\OR%
3542
\equal{\keyname}{below right}}{%
3543
\IfSubStr{\keyvalue}{ of }{%
3544
\pgfkeys{/tikzuml/statedeephistory/.cd, no coords}%
3545
}{}%
3546
}{}%
3547
\ifx\keyvalue\pgfkeysnovalue%
3548
\pgfkeys{/tikzuml/statedeephistory/.cd, style/.append style/.expand once={\keyname}}%
3549
\else%
3550
\pgfkeys{/tikzuml/statedeephistory/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
3551
\fi%
3552
%\errmessage{TIKZUML ERROR : in umlstatedeephistory, invalid option \keyname}%
3553
}%
3554
}%
3555
\pgfkeys{/tikzuml/statedeephistory/.cd, #1}%
3556
\pgfkeys{/tikzuml/statedeephistory/.cd, x/.get=\tikzumlStateDeepHistoryX, y/.get=\tikzumlStateDeepHistoryY, width/.get=\tikzumlStateDeepHistoryMinimumWidth,%
3557
name/.get=\tikzumlStateDeepHistoryName, color/.get=\tikzumlStateDeepHistoryColor%
3558
}%
3559
%
3560
\def\tikzumlStateDeepHistoryPos{\tikzumlStateDeepHistoryX,\tikzumlStateDeepHistoryY}%
3561
%
3562
\iftikzumlstatedeephistoryWithoutCoords%
3563
\node[circle, minimum size=\tikzumlStateDeepHistoryMinimumWidth, draw=\tikzumlStateDeepHistoryColor, /tikzuml/statedeephistory/style] (\tikzumlStateDeepHistoryName) {\pictureddeephistory{draw=\tikzumlStateDeepHistoryColor}};%
3564
\else%
3565
\node[circle, minimum size=\tikzumlStateDeepHistoryMinimumWidth, draw=\tikzumlStateDeepHistoryColor, /tikzuml/statedeephistory/style] (\tikzumlStateDeepHistoryName) at (\tikzumlStateDeepHistoryPos) {\pictureddeephistory{draw=\tikzumlStateDeepHistoryColor}};%
3566
\fi%
3567
%
3568
% add to fit
3569
\ifnum\c@tikzumlStateLevel>0%
3570
\edef\tikzumlStateFitOld{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
3571
\expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitOld (\tikzumlStateDeepHistoryName)}%
3572
\stepcounter{tikzumlStateSubStateNum}%
3573
\fi%
3574
\stepcounter{tikzumlStateDeepHistoryNum}%
3575
}%
3576
%
3577
% define a uml state
3578
% args : name of the state
3579
% content of the state
3580
% optional : x,y: coordinates of the state
3581
% width: width of the state node
3582
% name: name of the state node
3583
% entry, do, exit: entry/do/exit action of the state
3584
% draw, fill, text: colors
3585
% style: to manage every default TikZ option
3586
% no coords: to tell that the state position is defined relatively
3587
% to another node (automatically used with TikZ options above, below, left, right, below left, ...)
3588
\newenvironment{umlstate}[2][]{%
3589
\ifnum\thetikzumlStateLevel>0%
3590
\let\tikzumlState@nameold\tikzumlState@fitname%
3591
\let\tikzumlState@parentold\tikzumlState@parent%
3592
\edef\tikzumlState@parent{\tikzumlState@parentold @@\tikzumlState@nameold}%
3593
\else%
3594
\def\tikzumlState@parent{}%
3595
\fi%
3596
%
3597
\stepcounter{tikzumlStateLevel}%
3598
%
3599
\pgfkeys{/tikzuml/state/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlStateDefaultWidth,%
3600
name/.initial={},%
3601
entry/.initial={}, do/.initial={}, exit/.initial={},%
3602
draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlStateDefaultFillColor,%
3603
text/.initial=\tikzumlDefaultTextColor, style/.style={},%
3604
no coords/.is if=tikzumlstateWithoutCoords,%
3605
no coords=false,%
3606
.unknown/.code={%
3607
\let\keyname=\pgfkeyscurrentname%
3608
\let\keyvalue=\pgfkeyscurrentvalue%
3609
\ifthenelse{\equal{\keyname}{above}\OR%
3610
\equal{\keyname}{left}\OR%
3611
\equal{\keyname}{below}\OR%
3612
\equal{\keyname}{right}\OR%
3613
\equal{\keyname}{above left}\OR%
3614
\equal{\keyname}{above right}\OR%
3615
\equal{\keyname}{below left}\OR%
3616
\equal{\keyname}{below right}}{%
3617
\IfSubStr{\keyvalue}{ of }{%
3618
\pgfkeys{/tikzuml/state/.cd, no coords}%
3619
}{}%
3620
}{}%
3621
\ifx\keyvalue\pgfkeysnovalue%
3622
\pgfkeys{/tikzuml/state/.cd, style/.append style/.expand once={\keyname}}%
3623
\else%
3624
\pgfkeys{/tikzuml/state/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
3625
\fi%
3626
% \errmessage{TIKZUML ERROR : in umlstate, invalid option \keyname}%
3627
}%
3628
}%
3629
\pgfkeys{/tikzuml/state/.cd, #1}%
3630
\pgfkeys{/tikzuml/state/.cd, x/.get=\tikzumlStateXShift, y/.get=\tikzumlStateYShift, width/.get=\tikzumlStateMinimumWidth, name/.get=\tikzumlStateName,%
3631
entry/.get=\tikzumlStateEntry, do/.get=\tikzumlStateDo, exit/.get=\tikzumlStateExit,%
3632
draw/.get=\tikzumlStateDrawColor, fill/.get=\tikzumlStateFillColor,%
3633
text/.get=\tikzumlStateTextColor%
3634
}%
3635
%
3636
\ifthenelse{\equal{\tikzumlStateName}{}}{%
3637
\edef\tikzumlState@name{#2}%
3638
}{%
3639
\edef\tikzumlState@name{\tikzumlStateName}%
3640
}%
3641
%
3642
\begingroup%
3643
\def\_{@}\edef\x{\endgroup%
3644
\def\noexpand\tikzumlState@fitname{\tikzumlState@name}}\x%
3645
%
3646
\let\tikzumlState@nodeNameold\tikzumlState@nodeName%
3647
\def\tikzumlState@caption{#2}%
3648
%
3649
\begingroup%
3650
\def\_{_}\edef\x{\endgroup%
3651
\def\noexpand\tikzumlState@nodeName{\tikzumlState@name}}\x%
3652
%
3653
\expandafter\gdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{}%
3654
%
3655
\setcounter{tikzumlStateSubStateNum}{0}%
3656
\setcounter{tikzumlStateText}{0}%
3657
%
3658
\def\tikzumlStateText{tikzumlEmpty}%
3659
\begin{scope}[xshift=\tikzumlStateXShift cm, yshift=\tikzumlStateYShift cm]%
3660
}{%
3661
%
3662
\def\tikzumlstaterootlabel{\phantom{\tikzumlState@nodeName}}%
3663
%
3664
\def\tikzumlstaterootinnerysep{0.5ex}%
3665
\def\tikzumlstatebodyinnerysep{2ex}%
3666
%
3667
\ifthenelse{\equal{\tikzumlStateEntry}{}}{}{%
3668
\ifnum\c@tikzumlStateText=0%
3669
\def\tikzumlStateText{entry/\tikzumlStateEntry}%
3670
\else%
3671
\let\tikzumlStateTextOld\tikzumlStateText%
3672
\ifthenelse{\equal{\tikzumlStateText}{tikzumlEmpty}}{%
3673
\def\tikzumlStateText{entry/\tikzumlStateEntry}%
3674
}{%
3675
\expandafter\def\expandafter\tikzumlStateText\expandafter{\tikzumlStateTextOld \\ entry/\tikzumlStateEntry}%
3676
}%
3677
\fi%
3678
\setcounter{tikzumlStateText}{1}%
3679
\ifnum\c@tikzumlStateSubStateNum=0%
3680
\def\tikzumlstatebodyinnerysep{0}%
3681
\def\tikzumlstaterootinnerysep{0}%
3682
\fi%
3683
}%
3684
\ifthenelse{\equal{\tikzumlStateDo}{}}{}{%
3685
\ifnum\c@tikzumlStateText=0%
3686
\def\tikzumlStateText{do/\tikzumlStateDo}%
3687
\else%
3688
\let\tikzumlStateTextOld\tikzumlStateText%
3689
\ifthenelse{\equal{\tikzumlStateText}{tikzumlEmpty}}{%
3690
\def\tikzumlStateText{do/\tikzumlStateDo}%
3691
}{%
3692
\expandafter\def\expandafter\tikzumlStateText\expandafter{\tikzumlStateTextOld \\ do/\tikzumlStateDo}%
3693
}%
3694
\fi%
3695
\setcounter{tikzumlStateText}{1}%
3696
\ifnum\c@tikzumlStateSubStateNum=0%
3697
\def\tikzumlstatebodyinnerysep{0}%
3698
\def\tikzumlstaterootinnerysep{0}%
3699
\fi%
3700
}%
3701
\ifthenelse{\equal{\tikzumlStateExit}{}}{}{%
3702
\ifnum\c@tikzumlStateText=0%
3703
\def\tikzumlStateText{exit/\tikzumlStateExit}%
3704
\else%
3705
\let\tikzumlStateTextOld\tikzumlStateText%
3706
\ifthenelse{\equal{\tikzumlStateText}{tikzumlEmpty}}{%
3707
\def\tikzumlStateText{exit/\tikzumlStateExit}%
3708
}{%
3709
\expandafter\def\expandafter\tikzumlStateText\expandafter{\tikzumlStateTextOld \\ exit/\tikzumlStateExit}%
3710
}%
3711
\fi%
3712
\setcounter{tikzumlStateText}{1}%
3713
\ifnum\c@tikzumlStateSubStateNum=0%
3714
\def\tikzumlstatebodyinnerysep{0}%
3715
\def\tikzumlstaterootinnerysep{0}%
3716
\fi%
3717
}%
3718
%
3719
\addtocounter{tikzumlStateLevel}{-1}%
3720
\begin{pgfonlayer}{state\thetikzumlStateLevel}%
3721
%
3722
% if contains nothing, one define a fictive node to enable the fit option
3723
\ifnum\c@tikzumlStateSubStateNum=0%
3724
\iftikzumlstateWithoutCoords%
3725
\node[inner ysep=\tikzumlstaterootinnerysep, minimum width=\tikzumlStateMinimumWidth, /tikzuml/state/style] (\tikzumlState@nodeName-root) {\tikzumlstaterootlabel};%
3726
\else%
3727
\node[inner ysep=\tikzumlstaterootinnerysep, minimum width=\tikzumlStateMinimumWidth, /tikzuml/state/style] (\tikzumlState@nodeName-root) at (0,0) {\tikzumlstaterootlabel};%
3728
\fi%
3729
\expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{(\tikzumlState@nodeName-root)}%
3730
\fi%
3731
%
3732
\ifnum\c@tikzumlStateLevel>0%
3733
\def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent\endcsname}%
3734
\expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent\endcsname{\tikzumlStateFitTmp (\tikzumlState@nodeName-body) (\tikzumlState@nodeName-caption)}%
3735
\stepcounter{tikzumlStateSubStateNum}%
3736
\fi%
3737
%
3738
\node[inner xsep=2ex, inner ysep=\tikzumlstatebodyinnerysep, fit = \csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname, /tikzuml/state/style ] (\tikzumlState@nodeName-body) {};%
3739
\def\tikzumlState@orig{body}%
3740
\ifnum\c@tikzumlStateText=1%
3741
\node[above=0] (\tikzumlState@nodeName-texttmp) at (\tikzumlState@nodeName-\tikzumlState@orig.north) {\begin{tabular}{l}\tikzumlStateText \end{tabular}};%
3742
\def\tikzumlState@orig{texttmp}%
3743
\fi%
3744
\node[above] (\tikzumlState@nodeName-captiontmp) at (\tikzumlState@nodeName-\tikzumlState@orig.north) {\tikzumlState@caption};%
3745
\ifnum\c@tikzumlStateText=1%
3746
\node[rounded corners, draw=\tikzumlStateDrawColor, fill=\tikzumlStateFillColor, name=\tikzumlState@nodeName, fit=(\tikzumlState@nodeName-body) (\tikzumlState@nodeName-texttmp) (\tikzumlState@nodeName-captiontmp)] {};%
3747
\else%
3748
\node[rounded corners, draw=\tikzumlStateDrawColor, fill=\tikzumlStateFillColor, name=\tikzumlState@nodeName, fit=(\tikzumlState@nodeName-body) (\tikzumlState@nodeName-captiontmp)] {};%
3749
\fi%
3750
\ifnum\c@tikzumlStateText=1%
3751
\node (\tikzumlState@nodeName-text) at (\tikzumlState@nodeName-texttmp) {\begin{tabular}{l}\tikzumlStateText \end{tabular}};%
3752
\fi%
3753
\node (\tikzumlState@nodeName-caption) at (\tikzumlState@nodeName-captiontmp) {\tikzumlState@caption};%
3754
\draw (\tikzumlState@nodeName-caption.south -| \tikzumlState@nodeName.north west) -- (\tikzumlState@nodeName-caption.south -| \tikzumlState@nodeName.north east);%
3755
\end{pgfonlayer}%
3756
\end{scope}%
3757
}%
3758
%
3759
% shortcut for empty state
3760
\newcommand{\umlbasicstate}[2][]{\begin{umlstate}[#1]{#2}\end{umlstate}}%
3761
%
3762
% command to add text in a state, to be used inside umlstate environment
3763
\newcommand{\umlstatetext}[1]{%
3764
\def\tikzumlStateText{#1}%
3765
\setcounter{tikzumlStateText}{1}%
3766
}%
3767
%
3768
% shortcuts for state transitions macros
3769
\newcommand{\umltrans}[3][]{%
3770
\ifthenelse{\equal{#2}{#3}}{%
3771
\umlrelation[style={tikzuml transition style}, recursive mode=transition, #1]{#2}{#3}%
3772
}{%
3773
\umlrelation[style={tikzuml transition style}, #1]{#2}{#3}%
3774
}%
3775
}%
3776
\newcommand{\umlHVtrans}[3][]{\umlHVrelation[style={tikzuml transition style}, #1]{#2}{#3}}%
3777
\newcommand{\umlVHtrans}[3][]{\umlVHrelation[style={tikzuml transition style}, #1]{#2}{#3}}%
3778
\newcommand{\umlVHVtrans}[3][]{\umlVHVrelation[style={tikzuml transition style}, #1]{#2}{#3}}%
3779
\newcommand{\umlHVHtrans}[3][]{\umlHVHrelation[style={tikzuml transition style}, #1]{#2}{#3}}%
3780
\newcommand{\umlCNtrans}[4][]{\umlCNrelation[style={tikzuml transition style}, #1]{#2}{#3}{#4}}%
3781
%
3782
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3783
% sequence diagrams %
3784
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3785
%
3786
\tikzstyle{tikzuml synchron-msg style}=[color=\tikzumlDefaultDrawColor, -triangle 45]%
3787
\tikzstyle{tikzuml asynchron-msg style}=[color=\tikzumlDefaultDrawColor, -angle 45]%
3788
\tikzstyle{tikzuml return-msg style}=[color=\tikzumlDefaultDrawColor, dashed, -angle 45]%
3789
\tikzstyle{tikzuml call return style}=[color=\tikzumlDefaultDrawColor, dashed, -angle 45]%
3790
\tikzstyle{tikzuml activity style}=[inner xsep=1ex, inner ysep=1ex]%
3791
%
3792
\newcounter{tikzumlObjectNum}%
3793
\newcounter{tikzumlCallLevel}%
3794
\newcounter{tikzumlCallNum}%
3795
\newcounter{tikzumlFragmentLevel}%
3796
\newcounter{tikzumlFragmentLevelNum}%
3797
\newcounter{tikzumlFragmentNum}%
3798
\newcounter{tikzumlFragmentPartNum}%
3799
\newcounter{tikzumlCallStartFragmentNum}%
3800
\newcounter{tikzumlCallEndFragmentNum}%
3801
%
3802
\newif\iftikzumlobjectNoDDots%
3803
\newif\iftikzumlcreatecallNoDDots%
3804
%
3805
% define a sequence diagram
3806
%
3807
\newenvironment{umlseqdiag}{%
3808
\gdef\tikzumlInCreateCall{0}%
3809
\setcounter{tikzumlObjectNum}{0}%
3810
\setcounter{tikzumlCallLevel}{0}%
3811
\setcounter{tikzumlCallNum}{0}%
3812
\setcounter{tikzumlFragmentLevel}{0}%
3813
\setcounter{tikzumlFragmentLevelNum}{0}%
3814
\setcounter{tikzumlFragmentNum}{0}%
3815
\setcounter{tikzumlFragmentPartNum}{0}%
3816
\setcounter{tikzumlCallStartFragmentNum}{0}%
3817
\setcounter{tikzumlCallEndFragmentNum}{0}%
3818
%
3819
\ifx \@umlactor \@empty
3820
\newcommand{\umlactor}[2][]{%
3821
\pgfkeys{/tikzuml/actorobj/.cd, .unknown/.code={%
3822
\let\keyname=\pgfkeyscurrentname%
3823
\let\keyvalue=\pgfkeyscurrentvalue%
3824
\ifthenelse{\equal{\keyname}{stereo}}{%
3825
\errmessage{TIKZUML ERROR : in umlactor, forbidden option stereo}%
3826
}{}%
3827
}%
3828
}%
3829
%
3830
\pgfkeys{/tikzuml/actorobj/.cd, ##1}%
3831
\umlobject[stereo=actor, ##1]{##2}%
3832
}%
3833
\else%
3834
\renewcommand{\umlactor}[2][]{%
3835
\pgfkeys{/tikzuml/actorobj/.cd, .unknown/.code={%
3836
\let\keyname=\pgfkeyscurrentname%
3837
\let\keyvalue=\pgfkeyscurrentvalue%
3838
\ifthenelse{\equal{\keyname}{stereo}}{%
3839
\errmessage{TIKZUML ERROR : in umlactor, forbidden option stereo}%
3840
}{}%
3841
}%
3842
}%
3843
%
3844
\pgfkeys{/tikzuml/actorobj/.cd, ##1}%
3845
\umlobject[stereo=actor, ##1]{##2}%
3846
}%
3847
\fi%
3848
\begin{scope}[font=\tikzumlDefaultFont]%
3849
}{%
3850
% draw lifelines of each object
3851
\begin{pgfonlayer}{lifelines}%
3852
\foreach \id in \tikzumlIdList {%
3853
\draw (\csname tikzumlLastChild@\id \endcsname)+(0,-2.5ex) node[inner sep=0, name=end-\id] {};%
3854
\draw[dotted] (\id) -- (end-\id);%
3855
}%
3856
\end{pgfonlayer}%
3857
\end{scope}%
3858
}%
3859
%
3860
% define the database symbol
3861
% optional : global tikzpicture styles
3862
\newcommand{\pictureddatabase}[1]{%
3863
\pgfkeys{/tikzuml/database/.cd, scale/.initial=1, .unknown/.code={}}%
3864
\pgfkeys{/tikzuml/database/.cd,#1}%
3865
\pgfkeys{/tikzuml/database/.cd, scale/.get=\tikzumlDatabaseScale}%
3866
%
3867
\begin{tikzpicture}[#1]%
3868
\node[fill, draw, ellipse, minimum width=\tikzumlDatabaseScale*4ex, minimum height=\tikzumlDatabaseScale*2ex, inner sep=0] (bottom) at (0,-2ex) {};%
3869
\node[fill, draw, ellipse, minimum width=\tikzumlDatabaseScale*4ex, minimum height=\tikzumlDatabaseScale*2ex, inner sep=0] (top) at (0,4ex) {};%
3870
\fill (bottom.west) rectangle (top.east);%
3871
\begin{scope}%
3872
\clip (-3.5ex,-0.5ex) rectangle (3.5ex,2.5ex);%
3873
\node[draw, dashed, ellipse, minimum width=\tikzumlDatabaseScale*4ex, minimum height=\tikzumlDatabaseScale*2ex, inner sep=0] (bottom2) at (0,-2ex) {};%
3874
\end{scope}%
3875
\node[draw, ellipse, minimum width=\tikzumlDatabaseScale*4ex, minimum height=\tikzumlDatabaseScale*2ex, inner sep=0] (top2) at (0,4ex) {};%
3876
\draw (bottom.west) -- (top.west) (bottom.east) -- (top.east);%
3877
\end{tikzpicture}%
3878
}%
3879
%
3880
% define the entity symbol
3881
% optional : global tikzpicture styles
3882
\newcommand{\picturedentity}[1]{%
3883
\pgfkeys{/tikzuml/entity/.cd, scale/.initial=1, .unknown/.code={}}%
3884
\pgfkeys{/tikzuml/entity/.cd,#1}%
3885
\pgfkeys{/tikzuml/entity/.cd, scale/.get=\tikzumlEntityScale}%
3886
%
3887
\begin{tikzpicture}[#1]%
3888
\node[fill, draw, circle, inner sep=0, minimum size=\tikzumlEntityScale*5ex] (center) at (0,0) {};%
3889
\draw (center.south) node[coordinate, name=bottom] {};%
3890
\draw (bottom)+(-2ex,0) node[coordinate, name=bottom-left] {};%
3891
\draw (bottom)+(2ex,0) node[coordinate, name=bottom-right] {};%
3892
\draw (center) -- (bottom);%
3893
\draw (bottom-left) -- (bottom-right);%
3894
\end{tikzpicture}%
3895
}%
3896
%
3897
% define the boundary symbol
3898
% optional : global tikzpicture styles
3899
\newcommand{\picturedboundary}[1]{%
3900
\pgfkeys{/tikzuml/boundary/.cd, scale/.initial=1, .unknown/.code={}}%
3901
\pgfkeys{/tikzuml/boundary/.cd,#1}%
3902
\pgfkeys{/tikzuml/boundary/.cd, scale/.get=\tikzumlBoundaryScale}%
3903
%
3904
\begin{tikzpicture}[#1]
3905
\node[fill, draw, circle, inner sep=0, minimum size=\tikzumlBoundaryScale*5ex] (center) at (0,0) {};
3906
\draw (center.west)+(-0.8ex,0) node[coordinate, name=left] {};
3907
\draw (left)+(0,0.2ex) node[coordinate, name=left-top] {};
3908
\draw (left)+(0,-0.2ex) node[coordinate, name=left-bottom] {};
3909
\draw (center) -- (left);
3910
\draw (left-top) -- (left-bottom);
3911
\end{tikzpicture}
3912
}%
3913
%
3914
% define the control symbol
3915
% optional : global tikzpicture styles
3916
\newcommand{\picturedcontrol}[1]{%
3917
\pgfkeys{/tikzuml/control/.cd, scale/.initial=1, .unknown/.code={}}%
3918
\pgfkeys{/tikzuml/control/.cd,#1}%
3919
\pgfkeys{/tikzuml/control/.cd, scale/.get=\tikzumlControlScale}%
3920
%
3921
\begin{tikzpicture}[#1, decoration={markings, mark=at position 0.25 with {\arrow{>}}}]
3922
\node[fill, draw, circle, inner sep=0, minimum size=\tikzumlControlScale*5ex, postaction={decorate}] (center) at (0,0) {};
3923
\end{tikzpicture}
3924
}%
3925
%
3926
% define a uml object for a sequence diagram
3927
% args : name of the object
3928
% optional : x, y: coordinates of the object
3929
% stereo: stereotype of the object (object, actor, database, boundary, control, entity, multiobject)
3930
% class: class of the object
3931
% scale: scale factor of the object symbol
3932
% draw, fill, text; colors
3933
% no ddots: when used, disable printing of double dots
3934
\newcommand{\umlobject}[2][]{
3935
\stepcounter{tikzumlObjectNum}%
3936
%
3937
\edef\tikzumlobject@ddot{:}%
3938
\pgfkeys{/tikzuml/obj/.cd, x/.initial=tikzumlEmpty, y/.initial=\tikzumlDefaultX, stereo/.initial=\tikzumlObjectDefaultStereo,%
3939
class/.initial={}, scale/.initial=1,%
3940
draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlObjectDefaultFillColor,%
3941
text/.initial=\tikzumlDefaultTextColor,%
3942
no ddots/.is if=tikzumlobjectNoDDots,%
3943
no ddots=false,%
3944
.unknown/.code={%
3945
\let\keyname=\pgfkeyscurrentname%
3946
\let\keyvalue=\pgfkeyscurrentvalue%
3947
\errmessage{TIKZUML ERROR : in umlobject, invalid option \keyname}%
3948
}%
3949
}%
3950
\pgfkeys{/tikzuml/obj/.cd, #1}%
3951
\pgfkeys{/tikzuml/obj/.cd, x/.get=\tikzumlObjectX, y/.get=\tikzumlObjectY,%
3952
stereo/.get=\tikzumlObjectStereo, class/.get=\tikzumlObjectClass,%
3953
scale/.get=\tikzumlObjectScale,%
3954
draw/.get=\tikzumlObjectDrawColor, fill/.get=\tikzumlObjectFillColor,%
3955
text/.get=\tikzumlObjectTextColor%
3956
}%
3957
%
3958
\iftikzumlobjectNoDDots%
3959
\edef\tikzumlobject@ddot{}%
3960
\fi%
3961
%
3962
\ifthenelse{\equal{\tikzumlObjectX}{tikzumlEmpty}}{%
3963
\pgfmathsetmacro{\tikzumlObjectX}{4*(\thetikzumlObjectNum-1)}%
3964
}{}%
3965
%
3966
\def\tikzumlObjectName{#2}%
3967
\expandafter\xdef\csname tikzumlLastChild@\tikzumlObjectName \endcsname{\tikzumlObjectName}%
3968
%
3969
\ifnum\thetikzumlObjectNum=1%
3970
\xdef\tikzumlIdList{\tikzumlObjectName}%
3971
\else%
3972
\let\tikzumlIdListOld\tikzumlIdList%
3973
\expandafter\xdef\expandafter\tikzumlIdList\expandafter{\tikzumlIdListOld,\tikzumlObjectName}%
3974
\fi%
3975
%
3976
\tikzstyle{tikzuml object box style}=[rectangle, text=\tikzumlObjectTextColor, font=\tikzumlDefaultFont]%
3977
%
3978
\ifthenelse{\equal{\tikzumlObjectStereo}{object}}{%
3979
\tikzstyle{tikzuml object box style}+=[draw=\tikzumlObjectDrawColor, fill=\tikzumlObjectFillColor]%
3980
}{%
3981
\ifthenelse{\equal{\tikzumlObjectStereo}{multi}}{%
3982
\tikzstyle{tikzuml object box style}+=[fill=\tikzumlObjectFillColor]%
3983
}{}%
3984
}%
3985
%
3986
\ifnum\tikzumlInCreateCall=1%
3987
\draw (\tikzumlCreateCallObjectSrc -| \tikzumlObjectX,0) node[tikzuml object box style] (\tikzumlObjectName) {\tikzumlObjectName\tikzumlobject@ddot\tikzumlObjectClass};%
3988
\else%
3989
\node[tikzuml object box style] (\tikzumlObjectName) at (\tikzumlObjectX,\tikzumlObjectY) {\tikzumlObjectName\tikzumlobject@ddot\tikzumlObjectClass};%
3990
\fi%
3991
%
3992
\ifthenelse{\equal{\tikzumlObjectStereo}{multi}}{%
3993
\draw (\tikzumlObjectName.north east)+(0.4ex,0.4ex) node[name=\tikzumlObjectName-tr, coordinate] {};
3994
\draw (\tikzumlObjectName.north west)+(0.4ex,0.4ex) node[name=\tikzumlObjectName-tl, coordinate] {};
3995
\draw (\tikzumlObjectName.south east)+(0.4ex,0.4ex) node[name=\tikzumlObjectName-br, coordinate] {};
3996
\draw (\tikzumlObjectName-tr)+(0.4ex,0.4ex) node[name=\tikzumlObjectName-ttr, coordinate] {};
3997
\draw (\tikzumlObjectName-tl)+(0.4ex,0.4ex) node[name=\tikzumlObjectName-ttl, coordinate] {};
3998
\draw (\tikzumlObjectName-br)+(0.4ex,0.4ex) node[name=\tikzumlObjectName-tbr, coordinate] {};
3999
\fill[fill=\tikzumlObjectFillColor] (\tikzumlObjectName-ttl |- \tikzumlObjectName.north) -- (\tikzumlObjectName-ttl) -- (\tikzumlObjectName-ttr) -- (\tikzumlObjectName-tbr) -- (\tikzumlObjectName-tbr -| \tikzumlObjectName.east) -- (\tikzumlObjectName.north east) -- (\tikzumlObjectName-ttl |- \tikzumlObjectName.north);
4000
\draw[draw=\tikzumlObjectDrawColor] (\tikzumlObjectName-ttl |- \tikzumlObjectName.north) -- (\tikzumlObjectName-ttl) -- (\tikzumlObjectName-ttr) -- (\tikzumlObjectName-tbr) -- (\tikzumlObjectName-tbr -| \tikzumlObjectName.east);
4001
\fill[fill=\tikzumlObjectFillColor] (\tikzumlObjectName-tl |- \tikzumlObjectName.north) -- (\tikzumlObjectName-tl) -- (\tikzumlObjectName-tr) -- (\tikzumlObjectName-br) -- (\tikzumlObjectName-br -| \tikzumlObjectName.east) -- (\tikzumlObjectName.north east) -- (\tikzumlObjectName-tl |- \tikzumlObjectName.north);
4002
\draw[draw=\tikzumlObjectDrawColor] (\tikzumlObjectName-tl |- \tikzumlObjectName.north) -- (\tikzumlObjectName-tl) -- (\tikzumlObjectName-tr) -- (\tikzumlObjectName-br) -- (\tikzumlObjectName-br -| \tikzumlObjectName.east);
4003
\draw[draw=\tikzumlObjectDrawColor] (\tikzumlObjectName.north west) rectangle (\tikzumlObjectName.south east);
4004
}{%
4005
\ifthenelse{\equal{\tikzumlObjectStereo}{object}}{}{%
4006
\node[above=1ex, name=\tikzumlObjectName-picture] at (\tikzumlObjectName) {\csname pictured\tikzumlObjectStereo \endcsname{draw=\tikzumlObjectDrawColor, fill=\tikzumlObjectFillColor, scale=\tikzumlObjectScale}};
4007
}%
4008
}%
4009
}%
4010
%
4011
% shortcuts for objects
4012
\newcommand{\umlbasicobject}[2][]{%
4013
\pgfkeys{/tikzuml/basicobj/.cd, .unknown/.code={%
4014
\let\keyname=\pgfkeyscurrentname%
4015
\let\keyvalue=\pgfkeyscurrentvalue%
4016
\ifthenelse{\equal{\keyname}{no ddots}}{%
4017
\errmessage{TIKZUML ERROR : in umlbasicobject, forbidden option no ddots}%
4018
}{}%
4019
}%
4020
}%
4021
\pgfkeys{/tikzuml/basicobj/.cd, #1}%
4022
\umlobject[no ddots, #1]{#2}%
4023
}%
4024
%
4025
\newcommand{\umldatabase}[2][]{%
4026
\pgfkeys{/tikzuml/databaseobj/.cd, .unknown/.code={%
4027
\let\keyname=\pgfkeyscurrentname%
4028
\let\keyvalue=\pgfkeyscurrentvalue%
4029
\ifthenelse{\equal{\keyname}{stereo}}{%
4030
\errmessage{TIKZUML ERROR : in umldatabase, forbidden option stereo}%
4031
}{}%
4032
}%
4033
}%
4034
\pgfkeys{/tikzuml/databaseobj/.cd, #1}%
4035
\umlobject[stereo=database, #1]{#2}%
4036
}%
4037
\newcommand{\umlentity}[2][]{%
4038
\pgfkeys{/tikzuml/entityobj/.cd, .unknown/.code={%
4039
\let\keyname=\pgfkeyscurrentname%
4040
\let\keyvalue=\pgfkeyscurrentvalue%
4041
\ifthenelse{\equal{\keyname}{stereo}}{%
4042
\errmessage{TIKZUML ERROR : in umlentity, forbidden option stereo}%
4043
}{}%
4044
}%
4045
}%
4046
\pgfkeys{/tikzuml/entityobj/.cd, #1}%
4047
\umlobject[stereo=entity, #1]{#2}%
4048
}%
4049
\newcommand{\umlcontrol}[2][]{%
4050
\pgfkeys{/tikzuml/controlobj/.cd, .unknown/.code={%
4051
\let\keyname=\pgfkeyscurrentname%
4052
\let\keyvalue=\pgfkeyscurrentvalue%
4053
\ifthenelse{\equal{\keyname}{stereo}}{%
4054
\errmessage{TIKZUML ERROR : in umlcontrol, forbidden option stereo}%
4055
}{}%
4056
}%
4057
}%
4058
\pgfkeys{/tikzuml/controlobj/.cd, #1}%
4059
\umlobject[stereo=control, #1]{#2}%
4060
}%
4061
\newcommand{\umlboundary}[2][]{%
4062
\pgfkeys{/tikzuml/boundaryobj/.cd, .unknown/.code={%
4063
\let\keyname=\pgfkeyscurrentname%
4064
\let\keyvalue=\pgfkeyscurrentvalue%
4065
\ifthenelse{\equal{\keyname}{stereo}}{%
4066
\errmessage{TIKZUML ERROR : in umlboundary, forbidden option stereo}%
4067
}{}%
4068
}%
4069
}%
4070
\pgfkeys{/tikzuml/boundaryobj/.cd, #1}%
4071
\umlobject[stereo=boundary, #1]{#2}%
4072
}%
4073
\newcommand{\umlmulti}[2][]{%
4074
\pgfkeys{/tikzuml/multiobj/.cd, .unknown/.code={%
4075
\let\keyname=\pgfkeyscurrentname%
4076
\let\keyvalue=\pgfkeyscurrentvalue%
4077
\ifthenelse{\equal{\keyname}{stereo}}{%
4078
\errmessage{TIKZUML ERROR : in umlmulti, forbidden option stereo}%
4079
}{}%
4080
}%
4081
}%
4082
\pgfkeys{/tikzuml/multiobj/.cd, #1}%
4083
\umlobject[stereo=multi, #1]{#2}%
4084
}%
4085
%
4086
\newcounter{tikzumlSDNodeNum}%
4087
%
4088
% define a hidden node to lengthen lifeline of a object
4089
% args : object node
4090
% optional : dt: distance between the sdnode and the last call defined on the lifeline of the object
4091
% name: name of the sdnode
4092
\newcommand{\umlsdnode}[2][]{%
4093
\pgfkeys{/tikzuml/sdnode/.cd, dt/.initial=0, name/.initial=tikzumlEmpty}%
4094
\pgfkeys{/tikzuml/sdnode/.cd, #1}%
4095
\pgfkeys{/tikzuml/sdnode/.cd, dt/.get=\tikzumlSDNodeDT, name/.get=\tikzumlSDNodeName}%
4096
%
4097
\ifthenelse{\equal{\tikzumlSDNodeName}{tikzumlEmpty}}{%
4098
\expandafter\def\expandafter\tikzumlSDNode@nodeName{sdnode-\thetikzumlSDNodeNum}%
4099
}{%
4100
\expandafter\def\expandafter\tikzumlSDNode@nodeName{\tikzumlSDNodeName}%
4101
}%
4102
%
4103
\stepcounter{tikzumlSDNodeNum}%
4104
%
4105
\begingroup%
4106
\def\_{_}\edef\x{\endgroup%
4107
\def\noexpand\tikzumlSDNode@objnodeName{#2}}\x%
4108
%
4109
\draw (\expandafter\csname tikzumlLastChild@\tikzumlSDNode@objnodeName \endcsname)+(0,-\tikzumlSDNodeDT ex) node[name=\tikzumlSDNode@nodeName,coordinate] {};%
4110
%
4111
% update last node drawn on sender lifeline
4112
\expandafter\xdef\csname tikzumlLastChild@\tikzumlSDNode@objnodeName \endcsname{\tikzumlSDNode@nodeName}%
4113
}%
4114
%
4115
\newlength{\tikzumlCall@xa}%
4116
\newlength{\tikzumlCall@xb}%
4117
%
4118
% define a uml operation call for sequence diagrams
4119
% args : call sender
4120
% call receiver
4121
% optional : dt: time delay from precedent event end
4122
% name: name of the call
4123
% op: operation name and input args
4124
% return: return value
4125
% type: type of the call (synchron, asynchron)
4126
% draw, fill, text: colors
4127
% padding: time padding from call start and to call end
4128
\newenvironment{umlcall}[3][]{%
4129
\stepcounter{tikzumlCallNum}%
4130
\def\tikzumlCallWithReturn{tikzumlFalse}%
4131
\edef\tikzumlCall@lastchildNum{\thetikzumlCallNum}% for testing presence of sub-calls
4132
\gdef\tikzumlCallBottom{0}%
4133
%
4134
\pgfkeys{/tikzuml/call/.cd, dt/.initial=\tikzumlCallDefaultDT, name/.initial={call-\thetikzumlCallNum},%
4135
op/.initial={}, return/.initial={}, type/.initial=\tikzumlCallDefaultType,%
4136
draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlCallDefaultFillColor,%
4137
text/.initial=\tikzumlDefaultTextColor,%
4138
padding/.initial=\tikzumlCallDefaultPadding,%
4139
.unknown/.code={%
4140
\let\keyname=\pgfkeyscurrentname%
4141
\let\keyvalue=\pgfkeyscurrentvalue%
4142
\ifthenelse{\equal{\keyname}{with return}}{%
4143
\def\tikzumlCallWithReturn{tikzumlTrue}%
4144
}{%
4145
\errmessage{TIKZUML ERROR : in umlcall, invalid option \keyname}%
4146
}%
4147
}%
4148
}%
4149
\pgfkeys{/tikzuml/call/.cd, #1}%
4150
\pgfkeys{/tikzuml/call/.cd, dt/.get=\tikzumlCallDT, name/.get=\tikzumlCallName, op/.get=\tikzumlCallOp,%
4151
return/.get=\tikzumlCallReturn, type/.get=\tikzumlCallType,%
4152
padding/.get=\tikzumlCallPadding,%
4153
draw/.get=\tikzumlCallDrawColor, fill/.get=\tikzumlCallFillColor,%
4154
text/.get=\tikzumlCallTextColor%
4155
}%
4156
%
4157
\edef\tikzumlfillcall{\tikzumlCallFillColor}%
4158
\edef\tikzumldrawcall{\tikzumlCallDrawColor}%
4159
\edef\tikzumltextcall{\tikzumlCallTextColor}%
4160
\edef\tikzumltypecall{\tikzumlCallType}%
4161
%
4162
\ifthenelse{\equal{\tikzumlCallDT}{tikzumlEmpty}}{%
4163
\ifnum\thetikzumlCallNum=1%
4164
\def\tikzumlCallDT{2}%
4165
\def\tikzumlcallSrc{2}%
4166
\else%
4167
\def\tikzumlCallDT{2}%
4168
\def\tikzumlcallSrc{1}%
4169
\fi%
4170
}{%
4171
\def\tikzumlcallSrc{0}%
4172
}%
4173
%
4174
\let\tikzumlCallStartNodeNameold\tikzumlCallStartNodeName%
4175
\def\tikzumlCallStartNodeName{#2}%
4176
\let\tikzumlCallEndNodeNameold\tikzumlCallEndNodeName%
4177
\def\tikzumlCallEndNodeName{#3}%
4178
\def\tikzumlcallheight{\tikzumlCallPadding}%
4179
%
4180
% managing time delays from previous/parent fragments
4181
\ifnum\thetikzumlCallStartFragmentNum>0%
4182
\let\tikzumlCallDTold\tikzumlCallDT%
4183
\pgfmathparse{0.5*\tikzumlFragment@paddingy+\tikzumlCallDTold}%
4184
\edef\tikzumlCallDT{\pgfmathresult}%
4185
\addtocounter{tikzumlCallStartFragmentNum}{-1}
4186
\fi%
4187
\ifnum\thetikzumlCallEndFragmentNum>0%
4188
\let\tikzumlCallDTold\tikzumlCallDT%
4189
\pgfmathparse{0.5*\tikzumlFragment@paddingy+\tikzumlCallDTold}%
4190
\edef\tikzumlCallDT{\pgfmathresult}%
4191
\addtocounter{tikzumlCallEndFragmentNum}{-1}
4192
\fi%
4193
\ifnum\thetikzumlFragmentPartNum>0%
4194
\let\tikzumlCallDTold\tikzumlCallDT%
4195
\pgfmathparse{0.5*\tikzumlFragment@paddingy+\tikzumlCallDTold}%
4196
\edef\tikzumlCallDT{\pgfmathresult}%
4197
\fi%
4198
%
4199
% managing parent-child structure
4200
\ifnum\thetikzumlCallLevel>0%
4201
\let\tikzumlCall@nameold\tikzumlCall@name%
4202
\edef\tikzumlCall@name{\tikzumlCallName}%
4203
\let\tikzumlCall@parentold\tikzumlCall@parent%
4204
\edef\tikzumlCall@parent{\tikzumlCall@parentold @@\tikzumlCall@nameold}%
4205
\else%
4206
\edef\tikzumlCall@parent{}%
4207
\edef\tikzumlCall@parentold{}%
4208
\edef\tikzumlCall@nameold{}
4209
\edef\tikzumlCall@name{\tikzumlCallName}%
4210
\fi%
4211
%
4212
\begingroup%
4213
\def\_{_}\edef\x{\endgroup%
4214
\def\noexpand\tikzumlCall@nodeName{\tikzumlCall@name}}\x%
4215
%
4216
\let\tikzumlCall@nodeNameold\tikzumlCall@nodeName%
4217
%
4218
\def\tikzumlcallstyle{tikzuml \tikzumlCallType-msg style}%
4219
%
4220
% top node of activity period of call sender
4221
\begin{pgfonlayer}{connections}%
4222
\pgfmathparse{\tikzumlCallDT+\tikzumlcallSrc}%
4223
\draw (\csname tikzumlLastChild@\tikzumlCallStartNodeName \endcsname)+(0,-\pgfmathresult ex) node[coordinate, name=tikzumlTmpNode] {};%
4224
\node[tikzuml activity style] (st-\tikzumlCall@nodeName) at (\tikzumlCallStartNodeName |- tikzumlTmpNode) {};%
4225
%
4226
% update last node drawn on sender lifeline
4227
\expandafter\xdef\csname tikzumlLastChild@\tikzumlCallStartNodeName \endcsname{st-\tikzumlCall@nodeName}%
4228
%
4229
% top node of activity period of call receiver
4230
\ifthenelse{\equal{\tikzumlCallStartNodeName}{\tikzumlCallEndNodeName}}{%
4231
\draw (st-\tikzumlCall@nodeName)+(0,-0.75*\tikzumlCallPadding ex) node[coordinate, name=tikzumlTmpNode] {};%
4232
\node[tikzuml activity style] (et-\tikzumlCall@nodeName) at (\tikzumlCallStartNodeName |- tikzumlTmpNode) {};%
4233
}{%
4234
\node[tikzuml activity style] (et-\tikzumlCall@nodeName) at (\tikzumlCallEndNodeName |- st-\tikzumlCall@nodeName) {};%
4235
}%
4236
%
4237
% update last node drawn on receiver lifeline
4238
\expandafter\xdef\csname tikzumlLastChild@\tikzumlCallEndNodeName \endcsname{et-\tikzumlCall@nodeName}%
4239
\xdef\tikzumlCallBottomSrc{et-\tikzumlCall@nodeName}%
4240
\end{pgfonlayer}%
4241
%
4242
\stepcounter{tikzumlCallLevel}%
4243
}{%
4244
\addtocounter{tikzumlCallLevel}{-1}%
4245
%
4246
% bottom nodes of activity periods of call sender and receiver
4247
\begin{pgfonlayer}{connections}%
4248
\ifnum\tikzumlCall@lastchildNum=\thetikzumlCallNum%
4249
%
4250
% this test occurs a bug with latex package preview
4251
\ifthenelse{\equal{\tikzumlCallStartNodeName}{\tikzumlCallEndNodeName}}{%
4252
\draw (\tikzumlCallBottomSrc)+(0,-\tikzumlCallPadding ex) node[coordinate, name=tikzumlTmpNode] {};%
4253
\node[tikzuml activity style] (eb-\tikzumlCall@nodeName) at (\tikzumlCallEndNodeName |- tikzumlTmpNode) {};%
4254
\draw (eb-\tikzumlCall@nodeName)+(0,-0.75*\tikzumlCallPadding ex) node[coordinate, name=tikzumlTmpNode] {};%
4255
\node[tikzuml activity style] (sb-\tikzumlCall@nodeName) at (\tikzumlCallStartNodeName |- tikzumlTmpNode) {};%
4256
}{%
4257
\ifthenelse{\equal{\tikzumlCallReturn}{tikzumlEmpty}}{%
4258
\pgfmathsetmacro{\tikzumlCallPaddingd}{0.5*\tikzumlCallPadding}%
4259
}{%
4260
\pgfmathsetmacro{\tikzumlCallPaddingd}{1.2*\tikzumlCallPadding}%
4261
}%
4262
\draw (\tikzumlCallBottomSrc)+(0,-\tikzumlCallPaddingd ex) node[coordinate, name=tikzumlTmpNode] {};%
4263
\node[tikzuml activity style] (eb-\tikzumlCall@nodeName) at (\tikzumlCallEndNodeName |- tikzumlTmpNode) {};%
4264
\node[tikzuml activity style] (sb-\tikzumlCall@nodeName) at (\tikzumlCallStartNodeName |- eb-\tikzumlCall@nodeName) {};%
4265
}%
4266
\xdef\tikzumlCallBottomSrc{sb-\tikzumlCall@nodeName}%
4267
\else%
4268
%
4269
% managing time delays from previous/parent fragments
4270
\ifnum\thetikzumlCallStartFragmentNum>0%
4271
\let\tikzumlcallheightold\tikzumlCallPadding%
4272
\pgfmathparse{\tikzumlcallheightold+0.5*\tikzumlFragment@paddingy}%
4273
\edef\tikzumlcallheight{\pgfmathresult}%
4274
\addtocounter{tikzumlCallStartFragmentNum}{-1}%
4275
\fi%
4276
\ifnum\thetikzumlCallEndFragmentNum>0%
4277
\let\tikzumlcallheightold\tikzumlCallPadding%
4278
\pgfmathparse{\tikzumlcallheightold+0.5*\tikzumlFragment@paddingy}%
4279
\edef\tikzumlcallheight{\pgfmathresult}%
4280
\addtocounter{tikzumlCallEndFragmentNum}{-1}%
4281
\fi%
4282
%
4283
\ifthenelse{\equal{\tikzumlCallStartNodeName}{\tikzumlCallEndNodeName}}{%
4284
\draw (\tikzumlCallBottomSrc)+(0,-\tikzumlcallheight ex) node[coordinate, name=tikzumlTmpNode] {};%
4285
\node[tikzuml activity style] (eb-\tikzumlCall@nodeName) at (\tikzumlCallEndNodeName |- tikzumlTmpNode) {};%
4286
\draw (eb-\tikzumlCall@nodeName)+(0,-0.75*\tikzumlCallPadding ex) node[coordinate, name=tikzumlTmpNode] {};%
4287
\node[tikzuml activity style] (sb-\tikzumlCall@nodeName) at (\tikzumlCallStartNodeName |- tikzumlTmpNode) {};%
4288
}{%
4289
\draw (\tikzumlCallBottomSrc)+(0,-\tikzumlcallheight ex) node[coordinate, name=tikzumlTmpNode] {};%
4290
\node[tikzuml activity style] (eb-\tikzumlCall@nodeName) at (\tikzumlCallEndNodeName |- tikzumlTmpNode) {};%
4291
\node[tikzuml activity style] (sb-\tikzumlCall@nodeName) at (\tikzumlCallStartNodeName |- eb-\tikzumlCall@nodeName) {};%
4292
}%
4293
%
4294
\xdef\tikzumlCallBottomSrc{sb-\tikzumlCall@nodeName}%
4295
\fi%
4296
\end{pgfonlayer}%
4297
%
4298
% draw activity periods
4299
\begin{pgfonlayer}{activity}%
4300
\ifthenelse{\equal{\tikzumlCallStartNodeName}{\tikzumlCallEndNodeName}}{%
4301
% draw root activity period only
4302
\ifnum\thetikzumlCallLevel=0%
4303
\draw[draw=\tikzumldrawcall, fill=\tikzumlfillcall] (st-\tikzumlCall@nodeName.north west) rectangle (sb-\tikzumlCall@nodeName.south east);%
4304
\else%
4305
% draw root activity from inner call
4306
\ifthenelse{\equal{\tikzumlCallStartNodeName}{\tikzumlCallEndNodeNameold}}{}{%
4307
\draw[draw=\tikzumldrawcall, fill=\tikzumlfillcall] (st-\tikzumlCall@nodeName.north west) rectangle (sb-\tikzumlCall@nodeName.south east);%
4308
}%
4309
\fi%
4310
}{%
4311
% draw root activity period
4312
\ifnum\thetikzumlCallLevel=0%
4313
\draw[draw=\tikzumldrawcall, fill=\tikzumlfillcall] (st-\tikzumlCall@nodeName.north west) rectangle (sb-\tikzumlCall@nodeName.south east);%
4314
\else%
4315
% draw root activity from inner call
4316
\ifthenelse{\equal{\tikzumlCallStartNodeName}{\tikzumlCallEndNodeNameold}}{}{%
4317
\draw[draw=\tikzumldrawcall, fill=\tikzumlfillcall] (st-\tikzumlCall@nodeName.north west) rectangle (sb-\tikzumlCall@nodeName.south east);%
4318
}%
4319
\fi%
4320
% draw receiver activity period
4321
\draw[draw=\tikzumldrawcall, fill=\tikzumlfillcall] (et-\tikzumlCall@nodeName.north west) rectangle (eb-\tikzumlCall@nodeName.south east);%
4322
}%
4323
\end{pgfonlayer}%
4324
\ifthenelse{\equal{\tikzumlCallDefaultFillColor}{\tikzumlCallFillColor}}{}{%
4325
\fill[\tikzumlfillcall] (st-\tikzumlCall@nodeName.north west) rectangle (sb-\tikzumlCall@nodeName.south east);%
4326
\draw[\tikzumldrawcall] (st-\tikzumlCall@nodeName.north west) rectangle (sb-\tikzumlCall@nodeName.south west) (st-\tikzumlCall@nodeName.north east) rectangle (sb-\tikzumlCall@nodeName.south east);%
4327
}%
4328
%
4329
% update last nodes drawn on sender and receiver lifelines
4330
\expandafter\xdef\csname tikzumlLastChild@\tikzumlCallEndNodeName \endcsname{eb-\tikzumlCall@nodeName}%
4331
\expandafter\xdef\csname tikzumlLastChild@\tikzumlCallStartNodeName \endcsname{sb-\tikzumlCall@nodeName}%
4332
%
4333
% draw call arrows
4334
\begin{pgfonlayer}{connections}%
4335
\ifthenelse{\equal{\tikzumlCallStartNodeName}{\tikzumlCallEndNodeName}}{%
4336
\draw[\tikzumlcallstyle, \tikzumldrawcall] (st-\tikzumlCall@nodeName.east) -- ++(2.5*\tikzumlCallPadding ex,0) %
4337
-- ++(0,-0.75*\tikzumlCallPadding ex) %
4338
node[font=\tikzumlDefaultFont, text=\tikzumltextcall, midway, right, name=\tikzumlCall@nodeName-op] {\tikzumlCallOp} %
4339
-- (et-\tikzumlCall@nodeName.east);%
4340
%
4341
% draw return arrow and update fit for parent fragment
4342
\ifthenelse{\equal{\tikzumltypecall}{synchron}}{%
4343
\ifthenelse{\NOT\equal{\tikzumlCallReturn}{}\OR\equal{\tikzumlCallWithReturn}{tikzumlTrue}}{%
4344
\ifnum\c@tikzumlFragmentLevel>0%
4345
\edef\tikzumlFragmentFitOld{\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname}%
4346
\expandafter\xdef\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname{\tikzumlFragmentFitOld (st-\tikzumlCall@nodeName) (et-\tikzumlCall@nodeName) (eb-\tikzumlCall@nodeName) (sb-\tikzumlCall@nodeName) (\tikzumlCall@nodeName-op) (\tikzumlCall@nodeName-return)}%
4347
\fi%
4348
%
4349
\draw[tikzuml call return style, \tikzumldrawcall] (eb-\tikzumlCall@nodeName.east) -- ++(2.5*\tikzumlCallPadding ex,0)
4350
-- ++(0,-0.75*\tikzumlCallPadding ex) %
4351
node[font=\tikzumlDefaultFont, text=\tikzumltextcall, midway, right, name=\tikzumlCall@nodeName-return] {\tikzumlCallReturn} %
4352
-- (sb-\tikzumlCall@nodeName.east);%
4353
}{%
4354
\ifnum\c@tikzumlFragmentLevel>0%
4355
\edef\tikzumlFragmentFitOld{\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname}%
4356
\expandafter\xdef\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname{\tikzumlFragmentFitOld (st-\tikzumlCall@nodeName) (et-\tikzumlCall@nodeName) (eb-\tikzumlCall@nodeName) (sb-\tikzumlCall@nodeName) (\tikzumlCall@nodeName-op)}%
4357
\fi%
4358
}%
4359
}{%
4360
\ifnum\c@tikzumlFragmentLevel>0%
4361
\edef\tikzumlFragmentFitOld{\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname}%
4362
\expandafter\xdef\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname{\tikzumlFragmentFitOld (st-\tikzumlCall@nodeName) (et-\tikzumlCall@nodeName) (eb-\tikzumlCall@nodeName) (sb-\tikzumlCall@nodeName) (\tikzumlCall@nodeName-op)}%
4363
\fi%
4364
}%
4365
}{%
4366
% draw call arrows
4367
\pgfextractx{\tikzumlCall@xa}{\pgfpointanchor{\tikzumlCallStartNodeName}{center}}%
4368
\pgfextractx{\tikzumlCall@xb}{\pgfpointanchor{\tikzumlCallEndNodeName}{center}}%
4369
%
4370
\ifthenelse{\tikzumlCall@xb>\tikzumlCall@xa}{%
4371
\draw[\tikzumlcallstyle, \tikzumldrawcall] (st-\tikzumlCall@nodeName.east) -- (et-\tikzumlCall@nodeName.west) %
4372
node[font=\tikzumlDefaultFont, text=\tikzumltextcall, midway, above=-0.4ex, name=\tikzumlCall@nodeName-op] {\tikzumlCallOp};%
4373
}{%
4374
\draw[\tikzumlcallstyle, \tikzumldrawcall] (st-\tikzumlCall@nodeName.west) -- (et-\tikzumlCall@nodeName.east) %
4375
node[font=\tikzumlDefaultFont, text=\tikzumltextcall, midway, above=-0.4ex, name=\tikzumlCall@nodeName-op] {\tikzumlCallOp};%
4376
}%
4377
%
4378
% draw return arrow and update fit for parent fragment
4379
\ifthenelse{\equal{\tikzumltypecall}{synchron}}{%
4380
\ifthenelse{\NOT\equal{\tikzumlCallReturn}{}\OR\equal{\tikzumlCallWithReturn}{tikzumlTrue}}{%
4381
\ifnum\c@tikzumlFragmentLevel>0%
4382
\edef\tikzumlFragmentFitOld{\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname}%
4383
\expandafter\xdef\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname{\tikzumlFragmentFitOld (st-\tikzumlCall@nodeName) (et-\tikzumlCall@nodeName) (eb-\tikzumlCall@nodeName) (sb-\tikzumlCall@nodeName) (\tikzumlCall@nodeName-op) (\tikzumlCall@nodeName-return)}%
4384
\fi%
4385
%
4386
\ifthenelse{\tikzumlCall@xb>\tikzumlCall@xa}{%
4387
\draw[tikzuml call return style, \tikzumldrawcall] (eb-\tikzumlCall@nodeName.west) -- (sb-\tikzumlCall@nodeName.east) %
4388
node[font=\tikzumlDefaultFont, text=\tikzumltextcall, midway, above=-0.4ex, name=\tikzumlCall@nodeName-return] {\tikzumlCallReturn};%
4389
}{%
4390
\draw[tikzuml call return style, \tikzumldrawcall] (eb-\tikzumlCall@nodeName.east) -- (sb-\tikzumlCall@nodeName.west) %
4391
node[font=\tikzumlDefaultFont, text=\tikzumltextcall, midway, above=-0.4ex, name=\tikzumlCall@nodeName-return] {\tikzumlCallReturn};%
4392
}%
4393
}{%
4394
\ifnum\c@tikzumlFragmentLevel>0%
4395
\edef\tikzumlFragmentFitOld{\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname}%
4396
\expandafter\xdef\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname{\tikzumlFragmentFitOld (st-\tikzumlCall@nodeName) (et-\tikzumlCall@nodeName) (eb-\tikzumlCall@nodeName) (sb-\tikzumlCall@nodeName) (\tikzumlCall@nodeName-op)}%
4397
\fi%
4398
}%
4399
}{%
4400
\ifnum\c@tikzumlFragmentLevel>0%
4401
\edef\tikzumlFragmentFitOld{\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname}%
4402
\expandafter\xdef\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname{\tikzumlFragmentFitOld (st-\tikzumlCall@nodeName) (et-\tikzumlCall@nodeName) (eb-\tikzumlCall@nodeName) (sb-\tikzumlCall@nodeName) (\tikzumlCall@nodeName-op)}%
4403
\fi%
4404
}%
4405
}%
4406
\end{pgfonlayer}%
4407
}%
4408
%
4409
% alias for function self call
4410
\newenvironment{umlcallself}[2][]{\begin{umlcall}[#1]{#2}{#2} }{\end{umlcall}}%
4411
%
4412
% define a combined fragment
4413
% optional : name: name of fragment
4414
% type: type of fragment (opt, alt, break, loop, par, critical, ignore, consider, assert, neg, weak, strict, ref)
4415
% label: label of fragment (ex : condition for opt, iterator for loop, ...)
4416
% inner xsep, inner ysep: padding of the fragment box
4417
% draw, fill, text: colors
4418
\newenvironment{umlfragment}[1][]{%
4419
% define a fragment separator
4420
% optional : label of the fragment part (ex : else for alt)
4421
\providecommand{\umlfpart}[1][]{%
4422
\stepcounter{tikzumlFragmentPartNum}%
4423
%
4424
\node[outer sep=0, inner xsep=\tikzumlFragmentXSep ex, inner ysep=\tikzumlFragmentYSep ex, fit=\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname, name=\tikzumlFragment@name-Part-tmp] {};%
4425
\node[anchor=east, name=\tikzumlFragment@name-PartType-\thetikzumlFragmentPartNum] at (\tikzumlFragment@name-Part-tmp.north west |- \tikzumlCallBottomSrc) {\phantom{\tikzumlFragmentType}};%
4426
\draw (\tikzumlFragment@name-PartType-\thetikzumlFragmentPartNum.north west |- \tikzumlCallBottomSrc)+(0,-0.4*\tikzumlFragment@paddingy ex) node[name=\tikzumlFragment@name-PartWest-\thetikzumlFragmentPartNum] {};%
4427
\draw (\tikzumlFragment@name-Part-tmp.north east |- \tikzumlCallBottomSrc)+(0,-0.4*\tikzumlFragment@paddingy ex) node[name=\tikzumlFragment@name-PartEast-\thetikzumlFragmentPartNum] {};%
4428
\draw[dashed] (\tikzumlFragment@name-PartWest-\thetikzumlFragmentPartNum) -- (\tikzumlFragment@name-PartEast-\thetikzumlFragmentPartNum);
4429
\draw (\tikzumlFragment@name-PartType-\thetikzumlFragmentPartNum)+(0,-0.4*\tikzumlFragment@paddingy ex) node[name=tikzumlTmpNode] {\phantom{\tikzumlFragmentType}};%
4430
\node[anchor=north west] at (tikzumlTmpNode.south west) {[##1]};%
4431
}%
4432
%
4433
\stepcounter{tikzumlFragmentNum}%
4434
%
4435
\pgfkeys{/tikzuml/fragment/.cd, name/.initial=fragment@\alph{tikzumlFragmentNum}, type/.initial=\tikzumlFragmentDefaultType,%
4436
label/.initial=tikzumlEmpty,%
4437
inner xsep/.initial=\tikzumlFragmentDefaultXSep, inner ysep/.initial=\tikzumlFragmentDefaultYSep,%
4438
draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlFragmentDefaultFillColor,%
4439
text/.initial=\tikzumlDefaultTextColor,%
4440
.unknown/.code={%
4441
\let\keyname=\pgfkeyscurrentname%
4442
\let\keyvalue=\pgfkeyscurrentvalue%
4443
\errmessage{TIKZUML ERROR : in umlfragment, invalid option \keyname}%
4444
}%
4445
}%
4446
\pgfkeys{/tikzuml/fragment/.cd, #1}%
4447
\pgfkeys{/tikzuml/fragment/.cd, name/.get=\tikzumlFragmentName, type/.get=\tikzumlFragmentType,%
4448
label/.get=\tikzumlFragmentLabel,%
4449
inner xsep/.get=\tikzumlFragmentXSep, inner ysep/.get=\tikzumlFragmentYSep,%
4450
draw/.get=\tikzumlFragmentDrawColor, fill/.get=\tikzumlFragmentFillColor,%
4451
text/.get=\tikzumlFragmentTextColor%
4452
}%
4453
%
4454
\ifthenelse{\equal{\tikzumlFragmentLabel}{tikzumlEmpty}}{%
4455
\def\tikzumlFragmentLabel{}%
4456
}{%
4457
\let\tikzumlFragmentLabelold\tikzumlFragmentLabel%
4458
\def\tikzumlFragmentLabel{[\tikzumlFragmentLabelold]}%
4459
}%
4460
%
4461
\ifnum\thetikzumlFragmentLevel>0%
4462
\let\tikzumlFragment@parentold\tikzumlFragment@parent%
4463
\let\tikzumlFragment@nameold\tikzumlFragment@name%
4464
\edef\tikzumlFragment@parent{\tikzumlFragment@nameold}%
4465
\else%
4466
\setcounter{tikzumlFragmentPartNum}{0}%
4467
\edef\tikzumlFragment@parent{}%
4468
\edef\tikzumlFragment@parentold{}%
4469
\edef\tikzumlFragment@nameold{}%
4470
\fi%
4471
%
4472
\edef\tikzumlFragment@name{\tikzumlFragmentName}%
4473
\expandafter\gdef\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname{}%
4474
%
4475
\stepcounter{tikzumlFragmentLevel}%
4476
%
4477
\ifnum\thetikzumlCallLevel>0%
4478
\stepcounter{tikzumlCallStartFragmentNum}%
4479
\fi%
4480
%
4481
\pgfmathparse{6*\tikzumlFragmentYSep}%
4482
\xdef\tikzumlFragment@paddingy{\pgfmathresult}%
4483
\if\c@tikzumlFragmentLevelNum=0%
4484
\setcounter{tikzumlFragmentLevelNum}{\thetikzumlFragmentLevel}%
4485
\fi%
4486
%
4487
% time delay adjustment for two consecutive fragments
4488
\ifnum\thetikzumlCallEndFragmentNum>0%
4489
\addtocounter{tikzumlCallEndFragmentNum}{-1}
4490
\fi%
4491
}{%
4492
%
4493
\addtocounter{tikzumlFragmentLevel}{-1}%
4494
%
4495
\ifnum\thetikzumlFragmentLevel>0%
4496
\edef\tikzumlFragmentFitOld{\csname tikzumlFragmentFit\tikzumlFragment@parent \endcsname}%
4497
\expandafter\xdef\csname tikzumlFragmentFit\tikzumlFragment@parent \endcsname{\tikzumlFragmentFitOld (\tikzumlFragment@name)}%
4498
\fi%
4499
%
4500
% draw working fragment box
4501
\begin{pgfonlayer}{fragment\thetikzumlFragmentLevel}%
4502
\node[outer sep=0, inner xsep=\tikzumlFragmentXSep ex, inner ysep=\tikzumlFragmentYSep ex, fit=\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname, name=\tikzumlFragment@name-back] {};%
4503
\end{pgfonlayer}%
4504
%
4505
% draw type and label
4506
\node[text=\tikzumlFragmentTextColor, font=\tikzumlDefaultFont, anchor=north east, name=\tikzumlFragment@name-type] %
4507
at (\tikzumlFragment@name-back.north west) {\tikzumlFragmentType};%
4508
\node[text=\tikzumlFragmentTextColor, font=\tikzumlDefaultFont, anchor=north west, name=\tikzumlFragment@name-label] %
4509
at (\tikzumlFragment@name-type.south west) {\tikzumlFragmentLabel};%
4510
%
4511
% draw final fragment box
4512
\begin{pgfonlayer}{fragment\thetikzumlFragmentLevel}%
4513
\node[draw=\tikzumlFragmentDrawColor, fill=\tikzumlFragmentFillColor, outer sep=0, inner sep=0, font=\tikzumlDefaultFont, fit=(\tikzumlFragment@name-back) (\tikzumlFragment@name-type) (\tikzumlFragment@name-label), name=\tikzumlFragment@name] {};%
4514
\end{pgfonlayer}%
4515
%
4516
\draw[draw=\tikzumlFragmentDrawColor] (\tikzumlFragment@name.north west) rectangle (\tikzumlFragment@name.south east);%
4517
\draw (\tikzumlFragment@name-type.south east)+(0,1ex) node[name=\tikzumlFragment@name-typetop, inner sep=0] {};%
4518
\draw (\tikzumlFragment@name-type.south east)+(-1ex,0) node[name=\tikzumlFragment@name-typeleft, inner sep=0] {};%
4519
\draw (\tikzumlFragment@name.north west) -| (\tikzumlFragment@name-typetop.center) -- (\tikzumlFragment@name-typeleft.center) -| (\tikzumlFragment@name.north west);%
4520
%
4521
\ifnum\thetikzumlCallLevel>0%
4522
\stepcounter{tikzumlCallEndFragmentNum}%
4523
\fi%
4524
}%
4525
%
4526
% define a constructor call
4527
% arg : call sender
4528
% name of constructed object
4529
% optional : x: coordinate of the new object
4530
% stereo: stereotype of the new object
4531
% class: class type of the new object
4532
% dt: time delay from last event
4533
% name: name of the call
4534
% draw, fill, text: colors
4535
% no ddots: when used, disable printing of double dots
4536
\newcommand{\umlcreatecall}[3][]{%
4537
\stepcounter{tikzumlCallNum}%
4538
\edef\tikzumlCall@lastchildNum{\thetikzumlCallNum}% for testing presence of sub-calls
4539
\gdef\tikzumlInCreateCall{1}%
4540
\pgfkeys{/tikzuml/createcall/.cd, x/.initial=tikzumlEmpty, stereo/.initial=\tikzumlObjectDefaultStereo, class/.initial={},%
4541
dt/.initial=\tikzumlCreateCallDefaultDT, name/.initial=call-\thetikzumlCallNum,%
4542
draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlCallDefaultFillColor,%
4543
text/.initial=\tikzumlDefaultTextColor,%
4544
draw obj/.initial=\tikzumlDefaultDrawColor, fill obj/.initial=\tikzumlObjectDefaultFillColor,%
4545
text obj/.initial=\tikzumlDefaultTextColor,%
4546
no ddots/.is if=tikzumlcreatecallNoDDots,%
4547
no ddots=false,%
4548
.unknown/.code={%
4549
\let\keyname=\pgfkeyscurrentname%
4550
\let\keyvalue=\pgfkeyscurrentvalue%
4551
\errmessage{TIKZUML ERROR : in umlcreatecall, invalid option \keyname}%
4552
}%
4553
}%
4554
\pgfkeys{/tikzuml/createcall/.cd, #1}%
4555
\pgfkeys{/tikzuml/createcall/.cd, x/.get=\tikzumlCreateCallX, stereo/.get=\tikzumlCreateCallStereo,%
4556
class/.get=\tikzumlCreateCallClass,%
4557
dt/.get=\tikzumlCreateCallDT, name/.get=\tikzumlCreateCallName,%
4558
draw/.get=\tikzumlCreateCallDrawColor, fill/.get=\tikzumlCreateCallFillColor,%
4559
text/.get=\tikzumlCreateCallTextColor,%
4560
draw obj/.get=\tikzumlCreateCallObjectDrawColor, fill obj/.get=\tikzumlCreateCallObjectFillColor,%
4561
text obj/.get=\tikzumlCreateCallObjectTextColor%
4562
}%
4563
%
4564
\def\tikzumlCreateCallSrc@name{#2}%
4565
%
4566
\begingroup%
4567
\def\_{_}\edef\x{\endgroup%
4568
\def\noexpand\tikzumlCreateCallSrc@nodeName{\tikzumlCreateCallSrc@name}}\x%
4569
%
4570
% managing time delays from previous/parent fragments
4571
\ifnum\thetikzumlCallStartFragmentNum>0%
4572
\let\tikzumlCreateCallDTold\tikzumlCreateCallDT%
4573
\pgfmathparse{0.5*\tikzumlFragment@paddingy+\tikzumlCreateCallDTold}%
4574
\edef\tikzumlCreateCallDT{\pgfmathresult}%
4575
\addtocounter{tikzumlCallStartFragmentNum}{-1}
4576
\fi%
4577
\ifnum\thetikzumlCallEndFragmentNum>0%
4578
\let\tikzumlCreateCallDTold\tikzumlCreateCallDT%
4579
\pgfmathparse{0.5*\tikzumlFragment@paddingy+\tikzumlCreateCallDTold}%
4580
\edef\tikzumlCreateCallDT{\pgfmathresult}%
4581
\addtocounter{tikzumlCallEndFragmentNum}{-1}
4582
\fi%
4583
\ifnum\thetikzumlFragmentPartNum>0%
4584
\let\tikzumlCreateCallDTold\tikzumlCreateCallDT%
4585
\pgfmathparse{0.5*\tikzumlFragment@paddingy+\tikzumlCreateCallDTold}%
4586
\edef\tikzumlCreateCallDT{\pgfmathresult}%
4587
\fi%
4588
%
4589
% managing parent-child structure
4590
\ifnum\thetikzumlCallLevel>0%
4591
\let\tikzumlCall@nameold\tikzumlCall@name%
4592
\def\tikzumlCall@name{\tikzumlCreateCallName}%
4593
\let\tikzumlCall@parentold\tikzumlCall@parent%
4594
\edef\tikzumlCall@parent{\tikzumlCall@parentold @@\tikzumlCall@nameold}%
4595
\else%
4596
\edef\tikzumlCall@parent{}%
4597
\edef\tikzumlCall@parentold{}%
4598
\edef\tikzumlCall@nameold{}
4599
\edef\tikzumlCall@name{\tikzumlCreateCallName}%
4600
\fi%
4601
%
4602
\begingroup%
4603
\def\_{_}\edef\x{\endgroup%
4604
\def\noexpand\tikzumlCreateCall@nodeName{\tikzumlCall@name}}\x%
4605
%
4606
\draw (\csname tikzumlLastChild@\tikzumlCreateCallSrc@nodeName \endcsname)+(0,-\tikzumlCreateCallDT ex) node[name=st-\tikzumlCreateCall@nodeName, tikzuml activity style] {};%
4607
%
4608
\xdef\tikzumlCreateCallObjectSrc{st-\tikzumlCreateCall@nodeName}%
4609
%
4610
\iftikzumlcreatecallNoDDots%
4611
\umlobject[x=\tikzumlCreateCallX, stereo=\tikzumlCreateCallStereo, class=\tikzumlCreateCallClass, draw=\tikzumlCreateCallObjectDrawColor, fill=\tikzumlCreateCallObjectFillColor, text=\tikzumlCreateCallObjectTextColor, no ddots]{#3}%
4612
\else
4613
\umlobject[x=\tikzumlCreateCallX, stereo=\tikzumlCreateCallStereo, class=\tikzumlCreateCallClass, draw=\tikzumlCreateCallObjectDrawColor, fill=\tikzumlCreateCallObjectFillColor, text=\tikzumlCreateCallObjectTextColor]{#3}%
4614
\fi
4615
%
4616
\draw (\csname tikzumlLastChild@\tikzumlCreateCallSrc@nodeName \endcsname |- #3)+(0,-0.5*\tikzumlCreateCallDT ex) node[name=sb-\tikzumlCreateCall@nodeName, tikzuml activity style] {};%
4617
%
4618
\expandafter\xdef\csname tikzumlLastChild@\tikzumlCreateCallSrc@nodeName \endcsname{sb-\tikzumlCreateCall@nodeName}%
4619
\xdef\tikzumlCallBottomSrc{sb-\tikzumlCreateCall@nodeName}%
4620
%
4621
\begin{pgfonlayer}{connections}%
4622
\draw[tikzuml synchron-msg style, \tikzumlCreateCallDrawColor] (st-\tikzumlCreateCall@nodeName) -- (#3) node[midway, above, font=\tikzumlDefaultFont, text=\tikzumlCreateCallTextColor, name=\tikzumlCreateCall@nodeName-op] {create};%
4623
\end{pgfonlayer}%
4624
%
4625
\ifnum\thetikzumlCallLevel=0%
4626
\begin{pgfonlayer}{activity}%
4627
\draw[draw=\tikzumlCreateCallDrawColor, fill=\tikzumlCreateCallFillColor] (st-\tikzumlCreateCall@nodeName.north west) rectangle (sb-\tikzumlCreateCall@nodeName.south east);%
4628
\end{pgfonlayer}%
4629
\fi%
4630
% add to fit fragment
4631
\ifnum\c@tikzumlFragmentLevel>0%
4632
\edef\tikzumlFragmentFitOld{\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname}%
4633
\expandafter\xdef\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname{\tikzumlFragmentFitOld (st-\tikzumlCreateCall@nodeName) (sb-\tikzumlCreateCall@nodeName) (\tikzumlCreateCall@nodeName-op) (#3) }%
4634
\fi%
4635
}
4636
%
4637
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4638
% component diagrams %
4639
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4640
%
4641
\tikzstyle{tikzuml connector style}=[color=\tikzumlDefaultDrawColor, -]%
4642
%
4643
\newcounter{tikzumlComponentLevel}%
4644
\newcounter{tikzumlComponentSubComponentNum}%
4645
\newcounter{tikzumlConnectorNum}%
4646
\setcounter{tikzumlConnectorNum}{1}%
4647
%
4648
\newif\iftikzumlcomponentWithoutCoords%
4649
%
4650
\newcommand{\picturedcomponent}[1]{%
4651
\pgfkeys{/tikzuml/component/picture/.cd, scale/.initial=1, .unknown/.code={}}%
4652
\pgfkeys{/tikzuml/component/picture/.cd,#1}%
4653
\pgfkeys{/tikzuml/component/picture/.cd, scale/.get=\tikzumlComponentScale}%
4654
\begin{tikzpicture}[#1]%
4655
\filldraw (0,0) rectangle (1ex,1.5ex);%
4656
\filldraw (-0.2ex,0.4ex) rectangle (0.2ex,0.6ex);%
4657
\filldraw (-0.2ex,0.9ex) rectangle (0.2ex,1.1ex);%
4658
\end{tikzpicture}%
4659
}%
4660
%
4661
% define a uml component
4662
% args : name of the component
4663
% content of the component
4664
% optional args : x,y coordinates of the component
4665
% width of the component node
4666
\newenvironment{umlcomponent}[2][]{%
4667
\ifnum\thetikzumlComponentLevel>0%
4668
\let\tikzumlComponent@nameold\tikzumlComponent@fitname%
4669
\let\tikzumlComponent@parentold\tikzumlComponent@parent%
4670
\edef\tikzumlComponent@parent{\tikzumlComponent@parentold @@\tikzumlComponent@nameold}%
4671
\else%
4672
\def\tikzumlComponent@parent{}%
4673
\fi%
4674
%
4675
\stepcounter{tikzumlComponentLevel}%
4676
%
4677
\pgfkeys{/tikzuml/component/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlComponentDefaultWidth, name/.initial={},%
4678
draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlComponentDefaultFillColor,%
4679
text/.initial=\tikzumlDefaultTextColor, style/.style={},%
4680
no coords/.is if=tikzumlcomponentWithoutCoords,%
4681
no coords=false,%
4682
.unknown/.code={%
4683
\let\keyname=\pgfkeyscurrentname%
4684
\let\keyvalue=\pgfkeyscurrentvalue%
4685
\ifthenelse{\equal{\keyname}{above}\OR%
4686
\equal{\keyname}{left}\OR%
4687
\equal{\keyname}{below}\OR%
4688
\equal{\keyname}{right}\OR%
4689
\equal{\keyname}{above left}\OR%
4690
\equal{\keyname}{above right}\OR%
4691
\equal{\keyname}{below left}\OR%
4692
\equal{\keyname}{below right}}{%
4693
\IfSubStr{\keyvalue}{ of }{%
4694
\pgfkeys{/tikzuml/component/.cd, no coords}%
4695
}{}%
4696
}{}%
4697
\ifx\keyvalue\pgfkeysnovalue%
4698
\pgfkeys{/tikzuml/component/.cd, style/.append style/.expand once={\keyname}}%
4699
\else%
4700
\pgfkeys{/tikzuml/component/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
4701
\fi%
4702
%\errmessage{TIKZUML ERROR : in umlcomponent, invalid option \keyname}%
4703
}%
4704
}%
4705
\pgfkeys{/tikzuml/component/.cd, #1}%
4706
\pgfkeys{/tikzuml/component/.cd, x/.get=\tikzumlComponentXShift, y/.get=\tikzumlComponentYShift,%
4707
width/.get=\tikzumlComponentMinimumWidth, name/.get=\tikzumlComponentName,%
4708
draw/.get=\tikzumlComponentDrawColor, fill/.get=\tikzumlComponentFillColor,%
4709
text/.get=\tikzumlComponentTextColor%
4710
}%
4711
%
4712
\ifthenelse{\equal{\tikzumlComponentName}{}}{%
4713
\edef\tikzumlComponent@name{#2}%
4714
}{%
4715
\edef\tikzumlComponent@name{\tikzumlComponentName}%
4716
}%
4717
%
4718
\begingroup%
4719
\def\_{@}\edef\x{\endgroup%
4720
\def\noexpand\tikzumlComponent@fitname{\tikzumlComponent@name}}\x%
4721
%
4722
\let\tikzumlComponent@nodeNameold\tikzumlComponent@nodeName%
4723
\def\tikzumlComponent@caption{#2}%
4724
%
4725
\begingroup%
4726
\def\_{_}\edef\x{\endgroup%
4727
\def\noexpand\tikzumlComponent@nodeName{\tikzumlComponent@name}}\x%
4728
%
4729
\expandafter\gdef\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname{}%
4730
%
4731
\setcounter{tikzumlComponentSubComponentNum}{0}%
4732
%
4733
\begin{scope}[xshift=\tikzumlComponentXShift cm, yshift=\tikzumlComponentYShift cm]%
4734
}{%
4735
\addtocounter{tikzumlComponentLevel}{-1}%
4736
\begin{pgfonlayer}{component\thetikzumlComponentLevel}%
4737
%
4738
% if contains nothing, one define a fictive node to enable the fit option
4739
\ifnum\c@tikzumlComponentSubComponentNum=0%
4740
\iftikzumlcomponentWithoutCoords%
4741
\node[inner ysep=0.5ex, minimum width=\tikzumlComponentMinimumWidth, font=\tikzumlDefaultFont, /tikzuml/component/style] (\tikzumlComponent@nodeName-root) {\phantom{\tikzumlComponent@nodeName}};%
4742
\else%
4743
\node[inner ysep=0.5ex, minimum width=\tikzumlComponentMinimumWidth, font=\tikzumlDefaultFont, /tikzuml/component/style] (\tikzumlComponent@nodeName-root) at (0,0) {\phantom{\tikzumlComponent@nodeName}};%
4744
\fi%
4745
\expandafter\xdef\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname{(\tikzumlComponent@nodeName-root)}%
4746
\fi%
4747
%
4748
\ifnum\c@tikzumlComponentLevel>0%
4749
\def\tikzumlComponentFitTmp{\csname tikzumlComponentFit\tikzumlComponent@parent\endcsname}%
4750
\expandafter\xdef\csname tikzumlComponentFit\tikzumlComponent@parent\endcsname{\tikzumlComponentFitTmp (\tikzumlComponent@nodeName-body) (\tikzumlComponent@nodeName-caption)}%
4751
\stepcounter{tikzumlComponentSubComponentNum}%
4752
\fi%
4753
%
4754
\node[inner sep=2ex, font=\tikzumlDefaultFont, fit = \csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname] (\tikzumlComponent@nodeName-body) {};%
4755
\node[above, font=\tikzumlDefaultFont] (\tikzumlComponent@nodeName-captiontmp) at (\tikzumlComponent@nodeName-body.north) {\tikzumlComponent@caption};%
4756
\node (\tikzumlComponent@nodeName-logotmp) at (\tikzumlComponent@nodeName-captiontmp.north -| \tikzumlComponent@nodeName-body.east) {\picturedcomponent{draw=\tikzumlComponentDrawColor, fill=\tikzumlComponentFillColor, font=\tikzumlDefaultFont} };%
4757
\node[draw=\tikzumlComponentDrawColor, fill=\tikzumlComponentFillColor, name=\tikzumlComponent@nodeName, /tikzuml/component/style, fit=(\tikzumlComponent@nodeName-body) (\tikzumlComponent@nodeName-captiontmp)] {};%
4758
\node[font=\tikzumlDefaultFont] (\tikzumlComponent@nodeName-caption) at (\tikzumlComponent@nodeName-captiontmp) {\tikzumlComponent@caption};%
4759
\draw (\tikzumlComponent@nodeName-caption.north -| \tikzumlComponent@nodeName.east) node[font=\tikzumlDefaultFont, xshift=-1ex, below=-1ex, name=\tikzumlComponent@nodeName-logo] {\picturedcomponent{draw=\tikzumlComponentDrawColor, fill=\tikzumlComponentFillColor, font=\tikzumlDefaultFont} };%
4760
\draw (\tikzumlComponent@nodeName-caption.south -| \tikzumlComponent@nodeName.north west) -- (\tikzumlComponent@nodeName-caption.south -| \tikzumlComponent@nodeName.north east);%
4761
\coordinate (\tikzumlComponent@nodeName-west-port) at (\tikzumlComponent@nodeName.west);
4762
\coordinate (\tikzumlComponent@nodeName-east-port) at (\tikzumlComponent@nodeName.east);
4763
\coordinate (\tikzumlComponent@nodeName-south-port) at (\tikzumlComponent@nodeName.south);
4764
\coordinate (\tikzumlComponent@nodeName-north-port) at (\tikzumlComponent@nodeName.north);
4765
\end{pgfonlayer}%
4766
\end{scope}%
4767
%
4768
% add to fit
4769
\ifnum\c@tikzumlPackageLevel>0%
4770
\edef\tikzumlPackageFitOld{\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname}%
4771
\expandafter\xdef\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname{\tikzumlPackageFitOld (\tikzumlComponent@nodeName)}%
4772
\stepcounter{tikzumlPackageClassNum}%
4773
\fi%
4774
}%
4775
%
4776
% shortcut for empty component
4777
\newcommand{\umlbasiccomponent}[2][]{\begin{umlcomponent}[#1]{#2} \end{umlcomponent}}%
4778
%
4779
\newcommand{\umlrequiredinterface}[2][]{%
4780
\def\tikzumlInterfaceWithPort{tikzumlFalse}%
4781
\pgfkeys{/tikzuml/requiredinterfacerelation/.cd, interface/.initial={}, distance/.initial=\tikzumlRequiredInterfaceDefaultDistance,%
4782
name/.initial=tikzumlEmpty, width/.initial=\tikzumlRequiredInterfaceDefaultWidth,%
4783
padding/.initial=\tikzumlRequiredInterfaceDefaultPadding,%
4784
draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlComponentDefaultFillColor,%
4785
.unknown/.code={%
4786
\let\keyname=\pgfkeyscurrentname%
4787
\let\keyvalue=\pgfkeyscurrentvalue%
4788
\ifthenelse{\equal{\keyname}{with port}}{%
4789
\def\tikzumlInterfaceWithPort{tikzumlTrue}%
4790
}{}%
4791
}%
4792
}%
4793
\pgfkeys{/tikzuml/requiredinterfacerelation/.cd, #1}%
4794
\pgfkeys{/tikzuml/requiredinterfacerelation/.cd, interface/.get=\tikzumlRequiredInterfaceLabel,%
4795
distance/.get=\tikzumlRequiredInterfaceDistance,%
4796
name/.get=\tikzumlRequiredInterfaceName,%
4797
width/.get=\tikzumlRequiredInterfaceWidth,%
4798
padding/.get=\tikzumlRequiredInterfacePadding,%
4799
draw/.get=\tikzumlRequiredInterfaceDrawColor,%
4800
fill/.get=\tikzumlRequiredInterfaceFillColor%
4801
}%
4802
%
4803
\ifthenelse{\equal{\tikzumlRequiredInterfaceName}{tikzumlEmpty}}{%
4804
\edef\tikzumlRequiredInterface@interfacename{#2-east-interface}%
4805
\edef\tikzumlRequiredInterface@portname{#2-east-port}%
4806
\edef\tikzumlRequiredInterface@paddingname{#2-east-padding}%
4807
}{%
4808
\edef\tikzumlRequiredInterface@interfacename{\tikzumlRequiredInterfaceName}%
4809
\edef\tikzumlRequiredInterface@portname{\tikzumlRequiredInterfaceName-port}%
4810
\edef\tikzumlRequiredInterface@paddingname{\tikzumlRequiredInterfaceName-padding}%
4811
}%
4812
%
4813
\edef\tikzumlRequiredInterface@name{#2}%
4814
%
4815
\begingroup%
4816
\def\_{_}\edef\x{\endgroup%
4817
\def\noexpand\tikzumlRequiredInterface@nodeName{\tikzumlRequiredInterface@name}}\x%
4818
%
4819
\begingroup%
4820
\def\_{_}\edef\x{\endgroup%
4821
\def\noexpand\tikzumlRequiredInterface@interfacenodeName{\tikzumlRequiredInterface@interfacename}}\x%
4822
%
4823
\begingroup%
4824
\def\_{_}\edef\x{\endgroup%
4825
\def\noexpand\tikzumlRequiredInterface@portnodeName{\tikzumlRequiredInterface@portname}}\x%
4826
%
4827
\begingroup%
4828
\def\_{_}\edef\x{\endgroup%
4829
\def\noexpand\tikzumlRequiredInterface@paddingnodeName{\tikzumlRequiredInterface@paddingname}}\x%
4830
%
4831
\ifthenelse{\equal{\tikzumlInterfaceWithPort}{tikzumlTrue}}{%
4832
\node[inner sep=0.5*\tikzumlRequiredInterfaceWidth, rectangle, draw=\tikzumlRequiredInterfaceDrawColor, fill=\tikzumlRequiredInterfaceFillColor] (\tikzumlRequiredInterface@portnodeName) at (\tikzumlRequiredInterface@nodeName.east) {};%
4833
}{%
4834
\node[inner sep=0] (\tikzumlRequiredInterface@nodeName-east-port) at (\tikzumlRequiredInterface@nodeName.east) {};%
4835
}%
4836
\begin{scope}%
4837
\draw (\tikzumlRequiredInterface@nodeName)+(\tikzumlRequiredInterfaceDistance,0) node[inner sep=0, text width=\tikzumlRequiredInterfaceWidth, circle, name=\tikzumlRequiredInterface@interfacenodeName-tmp] {};%
4838
\clip (\tikzumlRequiredInterface@interfacenodeName-tmp.north) rectangle (\tikzumlRequiredInterface@interfacenodeName-tmp.south -| \tikzumlRequiredInterface@interfacenodeName-tmp.west);%
4839
\node[inner sep=0, text width=\tikzumlRequiredInterfaceWidth, circle, draw=\tikzumlRequiredInterfaceDrawColor] (\tikzumlRequiredInterface@interfacenodeName) at (\tikzumlRequiredInterface@interfacenodeName-tmp) {};%
4840
\end{scope}%
4841
\node[above] at (\tikzumlRequiredInterface@interfacenodeName.north) {\tikzumlRequiredInterfaceLabel};%
4842
%
4843
\umlrelation[style={tikzuml connector style}, #1]{\tikzumlRequiredInterface@portnodeName}{\tikzumlRequiredInterface@interfacenodeName}%
4844
%
4845
\draw (\tikzumlRequiredInterface@interfacenodeName)+(\tikzumlRequiredInterfacePadding,0) node[name=\tikzumlRequiredInterface@paddingnodeName] {};%
4846
%
4847
% add to fit
4848
\ifnum\c@tikzumlComponentLevel>0%
4849
\def\tikzumlComponentFitTmp{\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname}%
4850
\expandafter\xdef\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname{\tikzumlComponentFitTmp (\tikzumlRequiredInterface@paddingnodeName) (\tikzumlRequiredInterface@portnodeName) }%
4851
\fi%
4852
}%
4853
%
4854
\newcommand{\umlprovidedinterface}[2][]{%
4855
\def\tikzumlInterfaceWithPort{tikzumlFalse}%
4856
\pgfkeys{/tikzuml/providedinterfacerelation/.cd, interface/.initial={}, distance/.initial=\tikzumlProvidedInterfaceDefaultDistance,%
4857
name/.initial=tikzumlEmpty, width/.initial=\tikzumlProvidedInterfaceDefaultWidth,%
4858
padding/.initial=\tikzumlProvidedInterfaceDefaultPadding,%
4859
draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlComponentDefaultFillColor,%
4860
.unknown/.code={%
4861
\let\keyname=\pgfkeyscurrentname%
4862
\let\keyvalue=\pgfkeyscurrentvalue%
4863
\ifthenelse{\equal{\keyname}{with port}}{%
4864
\def\tikzumlInterfaceWithPort{tikzumlTrue}%
4865
}{}%
4866
}%
4867
}%
4868
\pgfkeys{/tikzuml/providedinterfacerelation/.cd, #1}%
4869
\pgfkeys{/tikzuml/providedinterfacerelation/.cd, interface/.get=\tikzumlProvidedInterfaceLabel,%
4870
distance/.get=\tikzumlProvidedInterfaceDistance,%
4871
name/.get=\tikzumlProvidedInterfaceName,%
4872
width/.get=\tikzumlProvidedInterfaceWidth,%
4873
padding/.get=\tikzumlProvidedInterfacePadding,%
4874
draw/.get=\tikzumlProvidedInterfaceDrawColor,%
4875
fill/.get=\tikzumlProvidedInterfaceFillColor%
4876
}%
4877
%
4878
\ifthenelse{\equal{\tikzumlProvidedInterfaceName}{tikzumlEmpty}}{%
4879
\edef\tikzumlProvidedInterface@interfacename{#2-west-interface}%
4880
\edef\tikzumlProvidedInterface@portname{#2-west-port}%
4881
\edef\tikzumlProvidedInterface@paddingname{#2-west-padding}%
4882
}{%
4883
\edef\tikzumlProvidedInterface@interfacename{\tikzumlProvidedInterfaceName}%
4884
\edef\tikzumlProvidedInterface@portname{\tikzumlProvidedInterfaceName-port}%
4885
\edef\tikzumlProvidedInterface@paddingname{\tikzumlProvidedInterfaceName-padding}%
4886
}%
4887
%
4888
\edef\tikzumlProvidedInterface@name{#2}%
4889
%
4890
\begingroup%
4891
\def\_{_}\edef\x{\endgroup%
4892
\def\noexpand\tikzumlProvidedInterface@nodeName{\tikzumlProvidedInterface@name}}\x%
4893
%
4894
\begingroup%
4895
\def\_{_}\edef\x{\endgroup%
4896
\def\noexpand\tikzumlProvidedInterface@interfacenodeName{\tikzumlProvidedInterface@interfacename}}\x%
4897
%
4898
\begingroup%
4899
\def\_{_}\edef\x{\endgroup%
4900
\def\noexpand\tikzumlProvidedInterface@portnodeName{\tikzumlProvidedInterface@portname}}\x%
4901
%
4902
\begingroup%
4903
\def\_{_}\edef\x{\endgroup%
4904
\def\noexpand\tikzumlProvidedInterface@paddingnodeName{\tikzumlProvidedInterface@paddingname}}\x%
4905
%
4906
\ifthenelse{\equal{\tikzumlInterfaceWithPort}{tikzumlTrue}}{%
4907
\node[inner sep=0.5*\tikzumlProvidedInterfaceWidth, rectangle, draw=\tikzumlProvidedInterfaceDrawColor, fill=\tikzumlProvidedInterfaceFillColor] (\tikzumlProvidedInterface@portnodeName) at (\tikzumlProvidedInterface@nodeName.west) {};%
4908
}{%
4909
\node[inner sep=0] (\tikzumlProvidedInterface@portnodeName) at (\tikzumlProvidedInterface@nodeName.west) {};%
4910
}%
4911
\draw (\tikzumlProvidedInterface@nodeName)+(-\tikzumlProvidedInterfaceDistance,0) node[inner sep=0, text width=\tikzumlProvidedInterfaceWidth, circle, draw=\tikzumlProvidedInterfaceDrawColor, fill=\tikzumlProvidedInterfaceFillColor, name=\tikzumlProvidedInterface@interfacenodeName] {};%
4912
\node[above] at (\tikzumlProvidedInterface@interfacenodeName.north)
4913
{\tikzumlProvidedInterfaceLabel};%
4914
%
4915
\umlrelation[style={tikzuml connector style}, #1]{\tikzumlProvidedInterface@portnodeName}{\tikzumlProvidedInterface@interfacenodeName}%
4916
%
4917
\draw (\tikzumlProvidedInterface@interfacenodeName)+(-\tikzumlProvidedInterfacePadding,0) node[name=\tikzumlProvidedInterface@paddingnodeName] {};%
4918
%
4919
% add to fit
4920
\ifnum\thetikzumlComponentLevel>0%
4921
\def\tikzumlComponentFitTmp{\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname}%
4922
\expandafter\xdef\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname{\tikzumlComponentFitTmp (\tikzumlProvidedInterface@paddingnodeName) (\tikzumlProvidedInterface@portnodeName) }%
4923
\fi%
4924
}%
4925
%
4926
\newlength{\tikzuml@AC@xa}%
4927
\newlength{\tikzuml@AC@ya}%
4928
\newlength{\tikzuml@AC@xb}%
4929
\newlength{\tikzuml@AC@yb}%
4930
\newlength{\tikzuml@AC@xi}%
4931
\newlength{\tikzuml@AC@yi}%
4932
\newlength{\tikzuml@AC@xic}%
4933
\newlength{\tikzuml@AC@yic}%
4934
\newlength{\tikzuml@AC@xio}%
4935
\newlength{\tikzuml@AC@yio}%
4936
\newlength{\tikzuml@AC@AB}%
4937
\newlength{\tikzuml@AC@lambda}%
4938
\newlength{\tikzuml@AC@xtrc}%
4939
\newlength{\tikzuml@AC@ytrc}%
4940
\newlength{\tikzuml@AC@xtlc}%
4941
\newlength{\tikzuml@AC@ytlc}%
4942
\newlength{\tikzuml@AC@xblc}%
4943
\newlength{\tikzuml@AC@yblc}%
4944
\newlength{\tikzuml@AC@xbrc}%
4945
\newlength{\tikzuml@AC@ybrc}%
4946
\newlength{\tikzuml@AC@middleArm}%
4947
%
4948
\newcommand{\umlassemblyconnectorsymbol}[2]{%
4949
\ifthenelse{\NOT\equal{\tikzumlAssemblyConnectorLabel}{}}{%
4950
\edef\tikzuml@ACStart@name{#1}%
4951
\edef\tikzuml@ACEnd@name{#2}%
4952
\edef\tikzuml@AC@width{\tikzumlAssemblyConnectorWidth}%
4953
%
4954
\begingroup%
4955
\def\_{_}\edef\x{\endgroup%
4956
\def\noexpand\tikzuml@ACStart@nodeName{\tikzuml@ACStart@name}}\x%
4957
%
4958
\begingroup%
4959
\def\_{_}\edef\x{\endgroup%
4960
\def\noexpand\tikzuml@ACEnd@nodeName{\tikzuml@ACEnd@name}}\x%
4961
%
4962
\begingroup%
4963
\def\_{_}\edef\x{\endgroup%
4964
\def\noexpand\tikzuml@ACInterface@nodeName{\tikzumlAssemblyConnectorSymbolName}}\x%
4965
%
4966
\pgfextractx{\tikzuml@AC@xa}{\pgfpointanchor{\tikzuml@ACStart@nodeName}{\tikzumlAssemblyConnectorStartAnchor}}%
4967
\pgfextracty{\tikzuml@AC@ya}{\pgfpointanchor{\tikzuml@ACStart@nodeName}{\tikzumlAssemblyConnectorStartAnchor}}%
4968
\pgfextractx{\tikzuml@AC@xb}{\pgfpointanchor{\tikzuml@ACEnd@nodeName}{\tikzumlAssemblyConnectorEndAnchor}}%
4969
\pgfextracty{\tikzuml@AC@yb}{\pgfpointanchor{\tikzuml@ACEnd@nodeName}{\tikzumlAssemblyConnectorEndAnchor}}%
4970
\pgfmathsetlength{\tikzuml@AC@xi}{0.5*\tikzuml@AC@xa+0.5*\tikzuml@AC@xb}%
4971
\pgfmathsetlength{\tikzuml@AC@yi}{0.5*\tikzuml@AC@ya+0.5*\tikzuml@AC@yb}%
4972
\pgfmathsetlength{\tikzuml@AC@AB}{veclen(\tikzuml@AC@xa-\tikzuml@AC@xb,\tikzuml@AC@ya-\tikzuml@AC@yb)}%
4973
\pgfmathsetlength{\tikzuml@AC@lambda}{0.25*\tikzuml@AC@width/\tikzuml@AC@AB}%
4974
\pgfmathsetlength{\tikzuml@AC@xic}{\tikzuml@AC@xi-\tikzuml@AC@lambda*(\tikzuml@AC@xb-\tikzuml@AC@xa)}%
4975
\pgfmathsetlength{\tikzuml@AC@yic}{\tikzuml@AC@yi-\tikzuml@AC@lambda*(\tikzuml@AC@yb-\tikzuml@AC@ya)}%
4976
\pgfmathsetlength{\tikzuml@AC@xio}{\tikzuml@AC@xi+\tikzuml@AC@lambda*(\tikzuml@AC@xb-\tikzuml@AC@xa)}%
4977
\pgfmathsetlength{\tikzuml@AC@yio}{\tikzuml@AC@yi+\tikzuml@AC@lambda*(\tikzuml@AC@yb-\tikzuml@AC@ya)}%
4978
\node[inner sep=0.5*\tikzuml@AC@width] (\tikzuml@ACInterface@nodeName-interface) at (\tikzuml@AC@xi,\tikzuml@AC@yi) {};%
4979
\node[inner sep=0, text width=\tikzuml@AC@width, circle, draw=\tikzumlAssemblyConnectorDrawColor, fill=\tikzumlAssemblyConnectorFillColor] (\tikzuml@ACInterface@nodeName-io) at (\tikzuml@AC@xio,\tikzuml@AC@yio) {};%
4980
\begin{scope}%
4981
\pgfmathsetlength{\tikzuml@AC@xtrc}{\tikzuml@AC@xic-2*\tikzuml@AC@lambda*(\tikzuml@AC@yb-\tikzuml@AC@ya)}%
4982
\pgfmathsetlength{\tikzuml@AC@ytrc}{\tikzuml@AC@yic+2*\tikzuml@AC@lambda*(\tikzuml@AC@xb-\tikzuml@AC@xa)}%
4983
\pgfmathsetlength{\tikzuml@AC@xbrc}{\tikzuml@AC@xic+2*\tikzuml@AC@lambda*(\tikzuml@AC@yb-\tikzuml@AC@ya)}%
4984
\pgfmathsetlength{\tikzuml@AC@ybrc}{\tikzuml@AC@yic-2*\tikzuml@AC@lambda*(\tikzuml@AC@xb-\tikzuml@AC@xa)}%
4985
\pgfmathsetlength{\tikzuml@AC@xtlc}{\tikzuml@AC@xic-3*\tikzuml@AC@lambda*(\tikzuml@AC@yb-\tikzuml@AC@ya+\tikzuml@AC@xb-\tikzuml@AC@xa)}%
4986
\pgfmathsetlength{\tikzuml@AC@ytlc}{\tikzuml@AC@yic+3*\tikzuml@AC@lambda*(\tikzuml@AC@xb-\tikzuml@AC@xa+\tikzuml@AC@ya-\tikzuml@AC@yb)}%
4987
\pgfmathsetlength{\tikzuml@AC@xblc}{\tikzuml@AC@xic+3*\tikzuml@AC@lambda*(\tikzuml@AC@yb-\tikzuml@AC@ya+\tikzuml@AC@xa-\tikzuml@AC@xb)}%
4988
\pgfmathsetlength{\tikzuml@AC@yblc}{\tikzuml@AC@yic-3*\tikzuml@AC@lambda*(\tikzuml@AC@xb-\tikzuml@AC@xa+\tikzuml@AC@yb-\tikzuml@AC@ya)}%
4989
\coordinate (\tikzuml@ACInterface@nodeName-trc) at (\tikzuml@AC@xtrc,\tikzuml@AC@ytrc);%
4990
\coordinate (\tikzuml@ACInterface@nodeName-brc) at (\tikzuml@AC@xbrc,\tikzuml@AC@ybrc);%
4991
\coordinate (\tikzuml@ACInterface@nodeName-tlc) at (\tikzuml@AC@xtlc,\tikzuml@AC@ytlc);%
4992
\coordinate (\tikzuml@ACInterface@nodeName-blc) at (\tikzuml@AC@xblc,\tikzuml@AC@yblc);%
4993
\clip (\tikzuml@ACInterface@nodeName-trc) -- (\tikzuml@ACInterface@nodeName-tlc) -- (\tikzuml@ACInterface@nodeName-blc) -- (\tikzuml@ACInterface@nodeName-brc) -- cycle;%
4994
\node[inner sep=0, text width=\tikzuml@AC@width, circle, draw=\tikzumlAssemblyConnectorDrawColor, fill=\tikzumlAssemblyConnectorFillColor] (\tikzuml@ACInterface@nodeName-ic) at (\tikzuml@AC@xic,\tikzuml@AC@yic) {};%
4995
\end{scope}%
4996
\node[above, font=\tikzumlDefaultFont] at (\tikzuml@ACInterface@nodeName-interface.north)
4997
{\tikzumlAssemblyConnectorLabel};%
4998
}{}%
4999
}%
5000
%
5001
\newcommand{\umlassemblyconnector}[3][]{%
5002
\def\tikzumlAssemblyConnectorWithPort{tikzumlFalse}%
5003
\def\tikzumlAssemblyConnectorFirstArm{tikzumlFalse}%
5004
\def\tikzumlAssemblyConnectorSecondArm{tikzumlFalse}%
5005
\def\tikzumlAssemblyConnectorMiddleArm{tikzumlFalse}%
5006
\def\tikzumlAssemblyConnectorLastArm{tikzumlFalse}%
5007
\pgfkeys{/tikzuml/assemblyconnectorrelation/.cd, geometry/.initial=--, interface/.initial={},%
5008
arm1/.initial={auto}, arm2/.initial={auto},%
5009
name/.initial=connector-\thetikzumlConnectorNum, width/.initial=1em,%
5010
anchor1/.initial={}, anchor2/.initial={},%
5011
draw/.initial=\tikzumlDefaultDrawColor,%
5012
fill assembly connector/.initial=\tikzumlAssemblyConnectorDefaultFillColor,%
5013
fill port/.initial=\tikzumlPortDefaultFillColor,%
5014
.unknown/.code={%
5015
\let\keyname=\pgfkeyscurrentname%
5016
\let\keyvalue=\pgfkeyscurrentvalue%
5017
\ifthenelse{\equal{\keyname}{with port}}{%
5018
\def\tikzumlAssemblyConnectorWithPort{tikzumlTrue}%
5019
}{%
5020
\ifthenelse{\equal{\keyname}{first arm}}{%
5021
\def\tikzumlAssemblyConnectorFirstArm{tikzumlTrue}%
5022
}{%
5023
\ifthenelse{\equal{\keyname}{second arm}}{%
5024
\def\tikzumlAssemblyConnectorSecondArm{tikzumlTrue}%
5025
}{%
5026
\ifthenelse{\equal{\keyname}{middle arm}}{%
5027
\def\tikzumlAssemblyConnectorMiddleArm{tikzumlTrue}%
5028
}{%
5029
\ifthenelse{\equal{\keyname}{last arm}}{%
5030
\def\tikzumlAssemblyConnectorLastArm{tikzumlTrue}%
5031
}{%
5032
}%
5033
}%
5034
}%
5035
}%
5036
}%
5037
}%
5038
}%
5039
\pgfkeys{/tikzuml/assemblyconnectorrelation/.cd, #1}%
5040
\pgfkeys{/tikzuml/assemblyconnectorrelation/.cd, geometry/.get=\tikzumlAssemblyConnectorGeometry,%
5041
name/.get=\tikzumlAssemblyConnectorName,%
5042
interface/.get=\tikzumlAssemblyConnectorLabel,%
5043
width/.get=\tikzumlAssemblyConnectorWidth,%
5044
arm1/.get=\tikzumlAssemblyConnectorStartArm,%
5045
arm2/.get=\tikzumlAssemblyConnectorEndArm,%
5046
anchor1/.get=\tikzumlAssemblyConnectorStartAnchorTmp,%
5047
anchor2/.get=\tikzumlAssemblyConnectorEndAnchorTmp,%
5048
draw/.get=\tikzumlAssemblyConnectorDrawColor,%
5049
fill assembly connector/.get=\tikzumlAssemblyConnectorFillColor,%
5050
fill port/.get=\tikzumlAssemblyConnectorPortFillColor%
5051
}%
5052
%
5053
\edef\tikzumlAssemblyConnectorStart@name{#2}%
5054
\edef\tikzumlAssemblyConnectorEnd@name{#3}%
5055
%
5056
\begingroup%
5057
\def\_{_}\edef\x{\endgroup%
5058
\def\noexpand\tikzumlAssemblyConnectorStart@nodeName{\tikzumlAssemblyConnectorStart@name}}\x%
5059
%
5060
\begingroup%
5061
\def\_{_}\edef\x{\endgroup%
5062
\def\noexpand\tikzumlAssemblyConnectorEnd@nodeName{\tikzumlAssemblyConnectorEnd@name}}\x%
5063
%
5064
\begingroup%
5065
\def\_{_}\edef\x{\endgroup%
5066
\def\noexpand\tikzumlAssemblyConnectorLabel@nodeName{\tikzumlAssemblyConnectorLabel}}\x%
5067
%
5068
\pgfextractx{\tikzuml@AC@xa}{\pgfpointanchor{\tikzumlAssemblyConnectorStart@nodeName}{center}}%
5069
\pgfextracty{\tikzuml@AC@ya}{\pgfpointanchor{\tikzumlAssemblyConnectorStart@nodeName}{center}}%
5070
\pgfextractx{\tikzuml@AC@xb}{\pgfpointanchor{\tikzumlAssemblyConnectorEnd@nodeName}{center}}%
5071
\pgfextracty{\tikzuml@AC@yb}{\pgfpointanchor{\tikzumlAssemblyConnectorEnd@nodeName}{center}}%
5072
%
5073
\ifthenelse{\equal{\tikzumlAssemblyConnectorGeometry}{--}}{%
5074
\ifthenelse{\tikzuml@AC@xb>\tikzuml@AC@xa}{%
5075
\def\tikzumlAssemblyConnectorStartAnchor{east}%
5076
\def\tikzumlAssemblyConnectorEndAnchor{west}%
5077
}{%
5078
\def\tikzumlAssemblyConnectorStartAnchor{west}%
5079
\def\tikzumlAssemblyConnectorEndAnchor{east}%
5080
}
5081
}{}%
5082
%
5083
\ifthenelse{\equal{\tikzumlAssemblyConnectorGeometry}{-|}}{%
5084
\ifthenelse{\tikzuml@AC@xb>\tikzuml@AC@xa}{%
5085
\def\tikzumlAssemblyConnectorStartAnchor{east}%
5086
}{%
5087
\def\tikzumlAssemblyConnectorStartAnchor{west}%
5088
}
5089
\ifthenelse{\tikzuml@AC@yb>\tikzuml@AC@ya}{%
5090
\def\tikzumlAssemblyConnectorEndAnchor{south}%
5091
}{%
5092
\def\tikzumlAssemblyConnectorEndAnchor{north}%
5093
}
5094
}{}%
5095
%
5096
\ifthenelse{\equal{\tikzumlAssemblyConnectorGeometry}{|-}}{%
5097
\ifthenelse{\tikzuml@AC@xb>\tikzuml@AC@xa}{%
5098
\def\tikzumlAssemblyConnectorEndAnchor{west}%
5099
}{%
5100
\def\tikzumlAssemblyConnectorEndAnchor{east}%
5101
}
5102
\ifthenelse{\tikzuml@AC@yb>\tikzuml@AC@ya}{%
5103
\def\tikzumlAssemblyConnectorStartAnchor{north}%
5104
}{%
5105
\def\tikzumlAssemblyConnectorStartAnchor{south}%
5106
}
5107
}{}%
5108
%
5109
\ifthenelse{\equal{\tikzumlAssemblyConnectorGeometry}{-|-}}{%
5110
\ifthenelse{\equal{\tikzumlAssemblyConnectorStartArm}{auto}}{%
5111
\ifthenelse{\equal{\tikzumlAssemblyConnectorEndArm}{auto}}{%
5112
\pgfmathsetlength{\tikzuml@AC@middleArm}{0.5 * \tikzuml@AC@xa + 0.5 * \tikzuml@AC@xb}%
5113
}{%
5114
\pgfmathsetlength{\tikzuml@AC@middleArm}{\tikzuml@AC@xb+\tikzumlAssemblyConnectorEndArm}%
5115
}%
5116
}{%
5117
\pgfmathsetlength{\tikzuml@AC@middleArm}{\tikzuml@AC@xa+\tikzumlAssemblyConnectorStartArm}%
5118
}%
5119
\pgfmathparse{\tikzuml@AC@middleArm>\tikzuml@AC@xa}
5120
\pgfmathparse{\tikzuml@AC@middleArm>\tikzuml@AC@xb}
5121
\ifthenelse{\lengthtest{\tikzuml@AC@middleArm>\tikzuml@AC@xa}}{%
5122
\def\tikzumlAssemblyConnectorStartAnchor{east}%
5123
}{%
5124
\def\tikzumlAssemblyConnectorStartAnchor{west}%
5125
}
5126
\ifthenelse{\lengthtest{\tikzuml@AC@middleArm>\tikzuml@AC@xb}}{%
5127
\def\tikzumlAssemblyConnectorEndAnchor{east}%
5128
}{%
5129
\def\tikzumlAssemblyConnectorEndAnchor{west}%
5130
}
5131
}{}%
5132
%
5133
\ifthenelse{\equal{\tikzumlAssemblyConnectorGeometry}{|-|}}{%
5134
\ifthenelse{\equal{\tikzumlAssemblyConnectorStartArm}{auto}}{%
5135
\ifthenelse{\equal{\tikzumlAssemblyConnectorEndArm}{auto}}{%
5136
\pgfmathsetlength{\tikzuml@AC@middleArm}{0.5 * \tikzuml@AC@ya + 0.5 * \tikzuml@AC@yb}%
5137
}{%
5138
\pgfmathsetlength{\tikzuml@AC@middleArm}{\tikzuml@AC@yb+\tikzumlAssemblyConnectorEndArm}%
5139
}%
5140
}{%
5141
\pgfmathsetlength{\tikzuml@AC@middleArm}{\tikzuml@AC@ya+\tikzumlAssemblyConnectorStartArm}%
5142
}%
5143
\ifthenelse{\tikzuml@AC@middleArm>\tikzuml@AC@ya}{%
5144
\def\tikzumlAssemblyConnectorStartAnchor{north}%
5145
}{%
5146
\def\tikzumlAssemblyConnectorStartAnchor{south}%
5147
}
5148
\ifthenelse{\tikzuml@AC@middleArm>\tikzuml@AC@yb}{%
5149
\def\tikzumlAssemblyConnectorEndAnchor{north}%
5150
}{%
5151
\def\tikzumlAssemblyConnectorEndAnchor{south}%
5152
}
5153
}{}%
5154
%
5155
\ifthenelse{\equal{\tikzumlAssemblyConnectorStartAnchorTmp}{}}{%
5156
}{%
5157
\def\tikzumlAssemblyConnectorStartAnchor{\tikzumlAssemblyConnectorStartAnchorTmp}%
5158
}%
5159
\ifthenelse{\equal{\tikzumlAssemblyConnectorEndAnchorTmp}{}}{%
5160
}{%
5161
\def\tikzumlAssemblyConnectorEndAnchor{\tikzumlAssemblyConnectorEndAnchorTmp}%
5162
}%
5163
%
5164
\node[inner sep=0] (\tikzumlAssemblyConnectorStart@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port-tmp) at (\tikzumlAssemblyConnectorStart@nodeName.\tikzumlAssemblyConnectorStartAnchor) {};%
5165
\node[inner sep=0] (\tikzumlAssemblyConnectorEnd@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port-tmp) at (\tikzumlAssemblyConnectorEnd@nodeName.\tikzumlAssemblyConnectorEndAnchor) {};%
5166
%
5167
\umlrelation[style={tikzuml connector style}, #1]{\tikzumlAssemblyConnectorStart@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port-tmp}{\tikzumlAssemblyConnectorEnd@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port-tmp}%
5168
%
5169
\ifthenelse{\equal{\tikzumlAssemblyConnectorWithPort}{tikzumlTrue}}{%
5170
\node[inner sep=0.5*\tikzumlAssemblyConnectorWidth, rectangle, draw=\tikzumlAssemblyConnectorDrawColor, fill=\tikzumlAssemblyConnectorPortFillColor] (\tikzumlAssemblyConnectorStart@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port) at (\tikzumlAssemblyConnectorStart@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port-tmp) {};%
5171
\node[inner sep=0.5*\tikzumlAssemblyConnectorWidth, rectangle, draw=\tikzumlAssemblyConnectorDrawColor, fill=\tikzumlAssemblyConnectorPortFillColor] (\tikzumlAssemblyConnectorEnd@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port) at (\tikzumlAssemblyConnectorEnd@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port-tmp) {};%
5172
}{%
5173
\node[inner sep=0] (\tikzumlAssemblyConnectorStart@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port) at (\tikzumlAssemblyConnectorStart@nodeName.\tikzumlAssemblyConnectorStartAnchor) {};%
5174
\node[inner sep=0] (\tikzumlAssemblyConnectorEnd@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port) at (\tikzumlAssemblyConnectorEnd@nodeName.\tikzumlAssemblyConnectorEndAnchor) {};%
5175
}%
5176
%
5177
\addtocounter{tikzumlRelationNum}{-1}%
5178
\ifthenelse{\equal{\tikzumlAssemblyConnectorName}{connector-\thetikzumlConnectorNum}}{%
5179
\edef\tikzumlAssemblyConnectorName{relation-\thetikzumlRelationNum}%
5180
\edef\tikzumlAssemblyConnectorSymbolName{\tikzumlAssemblyConnectorLabel@nodeName}%
5181
}{%
5182
\edef\tikzumlAssemblyConnectorSymbolName{\tikzumlAssemblyConnectorName}%
5183
}%
5184
%
5185
\stepcounter{tikzumlRelationNum}%
5186
%
5187
\ifthenelse{\equal{\tikzumlAssemblyConnectorGeometry}{--}}{%
5188
\umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorStart@nodeName}{\tikzumlAssemblyConnectorEnd@nodeName}%
5189
}{%
5190
\ifthenelse{\equal{\tikzumlAssemblyConnectorGeometry}{-|}}{%
5191
\ifthenelse{\equal{\tikzumlAssemblyConnectorFirstArm}{tikzumlTrue}}{%
5192
\umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorStart@nodeName}{\tikzumlAssemblyConnectorName-2}%
5193
}{%
5194
\umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorName-2}{\tikzumlAssemblyConnectorEnd@nodeName}%
5195
}%
5196
}{%
5197
\ifthenelse{\equal{\tikzumlAssemblyConnectorGeometry}{|-}}{%
5198
\ifthenelse{\equal{\tikzumlAssemblyConnectorFirstArm}{tikzumlTrue}}{%
5199
\umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorStart@nodeName}{\tikzumlAssemblyConnectorName-2}%
5200
}{%
5201
\umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorName-2}{\tikzumlAssemblyConnectorEnd@nodeName}%
5202
}%
5203
}{%
5204
\ifthenelse{\equal{\tikzumlAssemblyConnectorGeometry}{-|-}}{%
5205
\ifthenelse{\equal{\tikzumlAssemblyConnectorFirstArm}{tikzumlTrue}}{%
5206
\umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorStart@nodeName}{\tikzumlAssemblyConnectorName-2}%
5207
}{%
5208
\ifthenelse{\equal{\tikzumlAssemblyConnectorLastArm}{tikzumlTrue}}{%
5209
\umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorName-4}{\tikzumlAssemblyConnectorEnd@nodeName}%
5210
}{%
5211
\umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorName-2}{\tikzumlAssemblyConnectorName-4}%
5212
}%
5213
}%
5214
}{%
5215
\ifthenelse{\equal{\tikzumlAssemblyConnectorGeometry}{|-|}}{%
5216
\ifthenelse{\equal{\tikzumlAssemblyConnectorFirstArm}{tikzumlTrue}}{%
5217
\umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorStart@nodeName}{\tikzumlAssemblyConnectorName-2}%
5218
}{%
5219
\ifthenelse{\equal{\tikzumlAssemblyConnectorLastArm}{tikzumlTrue}}{%
5220
\umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorName-4}{\tikzumlAssemblyConnectorEnd@nodeName}%
5221
}{%
5222
\umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorName-2}{\tikzumlAssemblyConnectorName-4}%
5223
}%
5224
}%
5225
}{}%
5226
}%
5227
}%
5228
}%
5229
}%
5230
\stepcounter{tikzumlConnectorNum}%
5231
}%
5232
%
5233
% shortcuts of \umlassemblyconnector
5234
\newcommand{\umlHVassemblyconnector}[3][]{%
5235
\pgfkeys{/tikzuml/HVassemblyconnector/.cd,%
5236
.unknown/.code={%
5237
\let\keyname=\pgfkeyscurrentname%
5238
\let\keyvalue=\pgfkeyscurrentvalue%
5239
\ifthenelse{\equal{\keyname}{geometry}}{%
5240
\errmessage{TIKZUML ERROR : in umlHVassemblyconnector, forbidden option geometry}%
5241
}{}%
5242
}}%
5243
\pgfkeys{/tikzuml/HVassemblyconnector/.cd, #1}%
5244
\umlassemblyconnector[geometry=-|, #1]{#2}{#3}%
5245
}%
5246
%
5247
\newcommand{\umlVHassemblyconnector}[3][]{%
5248
\pgfkeys{/tikzuml/VHassemblyconnector/.cd,%
5249
.unknown/.code={%
5250
\let\keyname=\pgfkeyscurrentname%
5251
\let\keyvalue=\pgfkeyscurrentvalue%
5252
\ifthenelse{\equal{\keyname}{geometry}}{%
5253
\errmessage{TIKZUML ERROR : in umlVHassemblyconnector, forbidden option geometry}%
5254
}{}%
5255
}%
5256
}%
5257
\pgfkeys{/tikzuml/VHassemblyconnector/.cd, #1}%
5258
\umlassemblyconnector[geometry=|-, #1]{#2}{#3}%
5259
}%
5260
%
5261
\newcommand{\umlHVHassemblyconnector}[3][]{%
5262
\pgfkeys{/tikzuml/HVHassemblyconnector/.cd,%
5263
.unknown/.code={%
5264
\let\keyname=\pgfkeyscurrentname%
5265
\let\keyvalue=\pgfkeyscurrentvalue%
5266
\ifthenelse{\equal{\keyname}{geometry}}{%
5267
\errmessage{TIKZUML ERROR : in umlHVHassemblyconnector, forbidden option geometry}%
5268
}{}%
5269
}}%
5270
\pgfkeys{/tikzuml/HVHassemblyconnector/.cd, #1}%
5271
\umlassemblyconnector[geometry=-|-, #1]{#2}{#3}%
5272
}%
5273
%
5274
\newcommand{\umlVHVassemblyconnector}[3][]{%
5275
\pgfkeys{/tikzuml/VHVassemblyconnector/.cd,%
5276
.unknown/.code={%
5277
\let\keyname=\pgfkeyscurrentname%
5278
\let\keyvalue=\pgfkeyscurrentvalue%
5279
\ifthenelse{\equal{\keyname}{geometry}}{%
5280
\errmessage{TIKZUML ERROR : in umlVHVassemblyconnector, forbidden option geometry}%
5281
}{}%
5282
}}%
5283
\pgfkeys{/tikzuml/VHVassemblyconnector/.cd, #1}%
5284
\umlassemblyconnector[geometry=|-|, #1]{#2}{#3}%
5285
}%
5286
%
5287
\newcommand{\umlport}[3][]{%
5288
\pgfkeys{/tikzuml/port/.cd, draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlPortDefaultFillColor,%
5289
width/.initial=\tikzumlPortDefaultWidth,%
5290
.unknown/.code={%
5291
\let\keyname=\pgfkeyscurrentname%
5292
\let\keyvalue=\pgfkeyscurrentvalue%
5293
\errmessage{TIKZUML ERROR : in umlport forbidden option \keyname}%
5294
}%
5295
}%
5296
\pgfkeys{/tikzuml/port/.cd, #1}%
5297
\pgfkeys{/tikzuml/port/.cd, width/.get=\tikzumlPortWidth,%
5298
draw/.get=\tikzumlPortDrawColor, fill/.get=\tikzumlPortFillColor}%
5299
\edef\tikzumlPort@name{#2}%
5300
\edef\tikzumlPort@anchor{#3}%
5301
\begingroup%
5302
\def\_{_}\edef\x{\endgroup%
5303
\def\noexpand\tikzumlPort@nodeName{\tikzumlPort@name}}\x%
5304
%
5305
\node[inner sep=0.5*\tikzumlPortWidth, rectangle, draw=\tikzumlPortDrawColor, fill=\tikzumlPortFillColor] (\tikzumlPort@nodeName-\tikzumlPort@anchor-port) at (\tikzumlPort@nodeName.\tikzumlPort@anchor) {};%
5306
}%
5307
%
5308
\newcommand{\umldelegateconnector}[3][]{%
5309
\def\tikzumlDelegateConnectorWithStartPort{tikzumlFalse}%
5310
\def\tikzumlDelegateConnectorWithEndPort{tikzumlFalse}%
5311
\pgfkeys{/tikzuml/delegateconnector/.cd,
5312
.unknown/.code={%
5313
\let\keyname=\pgfkeyscurrentname%
5314
\let\keyvalue=\pgfkeyscurrentvalue%
5315
\ifthenelse{\equal{\keyname}{stereo}}{%
5316
\errmessage{TIKZUML ERROR : in umldelegateconnector, forbidden option stereo}%
5317
}{}%
5318
}}%
5319
\pgfkeys{/tikzuml/delegateconnector/.cd, #1}%
5320
\umlrelation[style={tikzuml connector style}, stereo=delegate, #1]{#2}{#3}%
5321
}%
5322
%
5323
% shortcuts of \umldelegateconnector
5324
\newcommand{\umlHVdelegateconnector}[3][]{%
5325
\pgfkeys{/tikzuml/HVdelegateconnector/.cd,%
5326
.unknown/.code={%
5327
\let\keyname=\pgfkeyscurrentname%
5328
\let\keyvalue=\pgfkeyscurrentvalue%
5329
\ifthenelse{\equal{\keyname}{geometry}\OR\equal{\keyname}{stereo}}{%
5330
\errmessage{TIKZUML ERROR : in umlHVdelegateconnector, forbidden option \keyname}%
5331
}{}%
5332
}}%
5333
\pgfkeys{/tikzuml/HVdelegateconnector/.cd, #1}%
5334
\umldelegateconnector[geometry=-|, #1]{#2}{#3}%
5335
}%
5336
%
5337
\newcommand{\umlVHdelegateconnector}[3][]{%
5338
\pgfkeys{/tikzuml/VHdelegateconnector/.cd,%
5339
.unknown/.code={%
5340
\let\keyname=\pgfkeyscurrentname%
5341
\let\keyvalue=\pgfkeyscurrentvalue%
5342
\ifthenelse{\equal{\keyname}{geometry}\OR\equal{\keyname}{stereo}}{%
5343
\errmessage{TIKZUML ERROR : in umlVHdelegateconnector, forbidden option \keyname}%
5344
}{}%
5345
}}%
5346
\pgfkeys{/tikzuml/VHdelegateconnector/.cd, #1}%
5347
\umldelegateconnector[geometry=|-, #1]{#2}{#3}%
5348
}%
5349
%
5350
\newcommand{\umlHVHdelegateconnector}[3][]{%
5351
\pgfkeys{/tikzuml/HVHdelegateconnector/.cd,%
5352
.unknown/.code={%
5353
\let\keyname=\pgfkeyscurrentname%
5354
\let\keyvalue=\pgfkeyscurrentvalue%
5355
\ifthenelse{\equal{\keyname}{geometry}\OR\equal{\keyname}{stereo}}{%
5356
\errmessage{TIKZUML ERROR : in umlHVHdelegateconnector, forbidden option \keyname}%
5357
}{}%
5358
}}%
5359
\pgfkeys{/tikzuml/HVHdelegateconnector/.cd, #1}%
5360
\umldelegateconnector[geometry=-|-, #1]{#2}{#3}%
5361
}%
5362
%
5363
\newcommand{\umlVHVdelegateconnector}[3][]{%
5364
\pgfkeys{/tikzuml/VHVdelegateconnector/.cd,%
5365
.unknown/.code={%
5366
\let\keyname=\pgfkeyscurrentname%
5367
\let\keyvalue=\pgfkeyscurrentvalue%
5368
\ifthenelse{\equal{\keyname}{geometry}\OR\equal{\keyname}{stereo}}{%
5369
\errmessage{TIKZUML ERROR : in umlVHVdelegateconnector, forbidden option \keyname}%
5370
}{}%
5371
}}%
5372
\pgfkeys{/tikzuml/VHVdelegateconnector/.cd, #1}%
5373
\umldelegateconnector[geometry=|-|, #1]{#2}{#3}%
5374
}%
5375
%%% End of tikz-uml.sty
5376
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5377