%%
%% This is file `pst-uml.sty',
%%
%% IMPORTANT NOTICE:
%%
%% Package `pst-uml.sty'
%%
%% Maurice Diamantini <
[email protected]>
%%
%% Jan 01, 2007
%%
%% This program can be redistributed and/or modified under the terms
%% of the LaTeX Project Public License Distributed from CTAN archives
%% in directory macros/latex/base/lppl.txt.
%%
%% DESCRIPTION:
%% `pst-uml' is a PSTricks package to draw UML diagrams
%%
% Inspir\'e des exemples de Denis GIROU
%
%
\def\filename{pst-uml}
\def\fileBut{Quelques macros pstricks pour diagrammes UML}
\def\fileversion{0.83}
\def\filedate{2007/01/03}
\def\fileMailAutor{
[email protected]}
%
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{\filename}%
[\filedate\space v\fileversion\space-\space\fileMailAutor]
\typeout{\space\space\space But\space:\space\fileBut.}
%
\RequirePackage{pstricks}
\RequirePackage{pst-node}
\RequirePackage{pst-tree}
\RequirePackage{multido}
\RequirePackage{calc}
\RequirePackage{ifthen}
\RequirePackage{graphicx} % a charger APRES pstricks
\RequirePackage{pst-xkey}
%
\pst@addfams{pst-uml}
%
% D\'efinition de quelques couleur par d\'efaut utilis\'ees pour UML
%
\definecolor{UMLgreyLight}{gray}{0.9}
\definecolor{UMLgrey80} {gray}{0.8}
%
% Quelques variable ou boite temporaires :
%
% compteur (i.e. entiers) pour les calculs temporaires
\newcounter{umlint@a}
\newcounter{umlint@b}
\newcounter{umlint@c}
\newcounter{umlint@d}
% longueurs pour les calculs temporaires
\newlength{\umldim@a}
\newlength{\umldim@b}
\newlength{\umldim@c}
\newlength{\umldim@d}
\newlength{\umldim@D}% Depth
\newlength{\umldim@H}% Height
\newlength{\umldim@W}% Width
% boite temporaire de memoristion des parametres
\newsavebox{\umlbox@a}
\newsavebox{\umlbox@b}
\newsavebox{\umlbox@c}
\newsavebox{\umlbox@d}
\newsavebox{\umlbox@out}
% boolean temporaires
\newboolean{umlbool@a}
\newboolean{umlbool@b}
\newboolean{umlbool@c}
\newboolean{umlbool@d}
% Affectation des valeurs par defaut standard de pstricks :
\psset{
% labelsep=0.5mm, % au lieu de plus/minus 2mm
labelsep=1mm, % au lieu de plus/minus 2mm
subgriddiv=1, % pour une grille de 1cm en pointilles
griddots=10,
gridlabels=6pt,
arrowscale=2,
}
\SpecialCoor
% Definition des parametres par d\'efaut (nouvelles longueurs, ...)
% % For debug : ShowPosition
% %
% % usage :
% % \ifthenelse{\value{umlDebug} > 0}{\ShowPosition}{}%
% %
% \newboolean{umlDebug}\setboolean{umlDebug}{false}
% Un entier pour Degoguer
% ATTENTION : si pb de port\'ee de variable (si besoin compteur global) :
% passer par \edef
%
\newcounter{umlDebug}
\define@key[psset]{pst-uml}{umlDebug}{%
\setcounter{umlDebug}{#1}%
%
% \setcounter{umlint@a}{#1}
% \setcounter{umlDebug}{\the\umlint@a}%
%
% \pst@cntg=#1\relax%
% \edef\psk@Integer{\the\pst@cntg}%
}
%
% Alignement du texte dans la boite umlstack (l, c, r)
\newcommand{\umlstr@Align}{}
\define@key[psset]{pst-uml}{umlAlign}{\renewcommand{\umlstr@Align}{#1}%
\@ifundefined{newcolumntype}{}{% set alignment for array package
\newcolumntype{U}{#1}}}
% Positionnement vertical de la boite umlstack (t, b, c)
\newcommand{\umlstr@Pos}{}
\define@key[psset]{pst-uml}{umlPos}{\renewcommand{\umlstr@Pos}{#1}}
% Distance de s\'eparation du texte à la boite umlstack
% Influe sur colsep pour l'espace horizontal et sur des strut pour
% l'espace vertical
\newlength\umldim@StackSep
\define@key[psset]{pst-uml}{umlStackSep}{\pssetlength\umldim@StackSep{#1}}
% coo\'eficient de modif de l'interligne de umlstack
\newcommand{\umlreal@StackLinesStretch}{}
\define@key[psset]{pst-uml}{umlStackLinesStretch}{%
\renewcommand{\umlreal@StackLinesStretch}{#1}}
% Largeur de la boite "umlStack"
\newlength\umldim@StackWidth
\define@key[psset]{pst-uml}{umlStackWidth}{\pssetlength\umldim@StackWidth{#1}}
% Largeur de la boite "classe"
\newlength\umldim@ClassWidth
\define@key[psset]{pst-uml}{umlClassWidth}{\pssetlength\umldim@ClassWidth{#1}}
% distance entre deux \hline dans la boite "classe"
\newlength\umldim@umlDoubleRuleSep
\define@key[psset]{pst-uml}{umlDoubleRuleSep}{\pssetlength\umldim@umlDoubleRuleSep{#1}}
% Chaine "Template"
% umlParameter
\newcommand{\umlstr@umlParameter}{}
\define@key[psset]{pst-uml}{umlParameter}{\renewcommand{\umlstr@umlParameter}{#1}}
% % un parametre boolean
% \newif\ifuml@Shadow
% \define@key[psset]{pst-uml}{umlShadow}[true]{\@nameuse{uml@Shadow#1}}
% un parametre boolean
\newboolean{umlbool@Shadow}
\define@key[psset]{pst-uml}{umlShadow}[true]{\setboolean{umlbool@Shadow}{#1}}
% Epaisseur de ligne pour le dessin d'un acteur
\newlength\umldim@ActorLineWidth
\define@key[psset]{pst-uml}{umlActorLineWidth}{\pssetlength\umldim@ActorLineWidth{#1}}
% Nom d'un objet (umlState, ...) N'EST PAS UTILISE !
\newcommand{\umlname@umlTitle}{}
\define@key[psset]{pst-uml}{umlTitle}{\renewcommand{\umlname@umlTitle}{#1}}
% Affectation des valeurs par defaut sprecifique a pst-uml:
\psset{
umlClassWidth=0,
umlShadow=true,
umlActorLineWidth=0.6mm,
umlParameter=,
umlTitle=,
umlDoubleRuleSep=2mm,
umlStackLinesStretch=0.85,
umlStackSep=0,
umlStackWidth=0,
umlAlign=c,
umlPos=c,
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Quelques commandes utilitaires generales :
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% pour passer plusieurs lignes (par \\) dans un parametre simple
%
% La difficult\'e \'etait de g\'erer l'option "StackSep" pour le
% haut et le bas du texte.
% ATTENTION il faut s'assurer que cette commande fonctionne même
% si le texte pass\'e en parametre commence ou finit par \hline !
%
%
\newcommand{\umlStack}[2][]{{%
\psset{#1}%
\setlength{\tabcolsep}{\umldim@StackSep}%
\renewcommand{\arraystretch}{\umlreal@StackLinesStretch}%
\ifthenelse{\lengthtest{\umldim@StackWidth=0pt}}{%
% dimensionnement automatique
\@ifundefined{newcolumntype}{% standard
\begin{tabular}[\umlstr@Pos]{\umlstr@Align}%
}{% for array package, columntype U was defined previous
\begin{tabular}[\umlstr@Pos]{U}%
}%
}{% else
% dimensionnement fixe
\@ifundefined{newcolumntype}{% see above
\begin{tabular*}{\umldim@StackWidth}[\umlstr@Pos]{\umlstr@Align}%
}{%
\begin{tabular*}{\umldim@StackWidth}[\umlstr@Pos]{U}%
}%
}% endif
% \begin{tabular}[\umlstr@Pos]{\umlstr@Align}%
\setlength{\umldim@a}{1.5ex+\umldim@StackSep}%
\rule{0pt}{\umldim@a}%
\\[-2.5ex]%
#2%
\\[-2.5ex]%
\setlength{\umldim@a}{-\umldim@StackSep}%
\rule[-\umldim@StackSep]{0pt}{0pt}%
% \end{tabular}%
\ifthenelse{\lengthtest{\umldim@StackWidth=0pt}}{%
% dimensionnement automatique
\end{tabular}%
}{% else
% dimensionnement fixe
\end{tabular*}%
}% endif
}}
% FONCTIONNE MAIS LE PREMIER \rule gene si #2 commence par \hline
% \newcommand{\umlStack}[2][]{{%
% \psset{#1}%
% \setlength{\tabcolsep}{\umldim@StackSep}%
% \renewcommand{\arraystretch}{\umlreal@StackLinesStretch}%
% \begin{tabular}{\umlstr@Align}%
% \setlength{\umldim@a}{1.5ex+\umldim@StackSep}%
% \rule{0pt}{\umldim@a}%
% #2%
% \setlength{\umldim@a}{-\umldim@StackSep}%
% \rule[-\umldim@StackSep]{0pt}{0pt}
% \end{tabular}%
% }}
% Pour creer une boite vide width, height
% Exemple \umlEmptyBox{7cm}{10cm}
\newcommand{\umlEmptyBox}[2]{%
\rule{#1}{0cm}%
\rule{0cm}{#2}%
}
% permet d'afficher <<MonStereoType>> sans serif.
\newcommand{\umlStereoType}[1]{%
{\footnotesize\ensuremath{\ll}}\textsf{#1}{\footnotesize\ensuremath{\gg}}%
}
% permet d'afficher un triangle plein vers la droite.
% Pas d'option pour l'instant
\newcommand{\umlTriRight}[1][]{{%
\psset{#1}%
\space
\begin{pspicture}(0,0)(1.1ex,1.1ex)%
\pstriangle[linewidth=0,fillstyle=solid,fillcolor=black,gangle=-90]%
(0.55ex,0.55ex)(1.1ex,1.1ex)%
\end{pspicture}%
\space
}}
% permet d'afficher un triangle plein vers la gauche.
% Pas d'option pour l'instant
\newcommand{\umlTriLeft}[1][]{{%
\psset{#1}%
\space
\begin{pspicture}(0,0)(1.1ex,1.1ex)%
\pstriangle[linewidth=0,fillstyle=solid,fillcolor=black,gangle=90]%
(0.55ex,0.55ex)(1.1ex,1.1ex)%
\end{pspicture}%
\space
}}
% For drawing a grid of 1cm in pointed line
% but \showgrid could be already define by another package
% PLANTE SI \showgrid EST REDEFINIE DANS fvrbext.sty
% \providecommand{\showgrid}{%
% \psset{subgriddiv=1,griddots=10,gridlabels=6pt,}
% \psgrid
% }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% La macro principal pour dessiner une classe :
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Le corps de la commande est entre {{ }} pour assurer des changements
% LOCAUX des valeurs de parametres (tels que \psset{...})
\newcommand{\umlClass}[3][]{{%
\psset{#1}% Reading keyOptions
\setlength{\doublerulesep}{\umldim@umlDoubleRuleSep}%
\def\next{#2}%
\ifx\next\empty%
% Title IS EMPTY (JAMAIS UTILISE ! : A VIRER ??)
\sbox{\umlbox@out}{\texttt{\umlStack[umlStackSep=1ex]{#3}}}%
\else%
% Title is NOT EMPTY
\def\next{#3}%
\ifx\next\empty%
% Body IS EMPTY
\sbox{\umlbox@out}{\textbf{\umlStack[umlStackSep=1ex]{#2}}}%
\else%
% Body is NOT EMPTY
\sbox{\umlbox@out}{\ttfamily%
\begin{tabular}{l}%
\hfil\normalfont\textbf{%
\setlength{\tabcolsep}{0pt}
\begin{tabular}{c}
#2
\end{tabular}
}%
\\ \hline%
#3%
\end{tabular}%
}%
\fi%
\fi%
% Output box is now define
%
% On dessine la boite finale :
\ifthenelse{\boolean{umlbool@Shadow}}{%
\psshadowbox[fillstyle=solid,framesep=0,fillcolor=UMLgrey80]%
{\usebox{\umlbox@out}}%
}{%
{\setlength{\fboxsep}{0pt}\fbox{\usebox{\umlbox@out}}}%
}%
%
% On superpose \'eventuellement le template (rectangle pointill\'e)
%
\settowidth{\umldim@a}{\umlstr@umlParameter}%
\ifthenelse{\lengthtest{\umldim@a=0pt}}{%
}{%
\settoheight{\umldim@H}{\usebox{\umlbox@out}}% Height
\setlength{\umldim@a}{1.5ex}% dx
\setlength{\umldim@b}{\umldim@H - 0.3ex}% Height - dy
%
\rput[br](\umldim@a,\umldim@b){%
\psframebox[fillstyle=solid,fillcolor=white,linestyle=dashed]%
{\Large\textbf{\umlstr@umlParameter}}%
}%
}%
%
}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Memorisation d'une classe dans une boite
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Surcourche à la commande de dessin de classe :
% CECI FONCTIONNE MAL (la boite cree s'appel "#" )
% Je n'ai pas reussi en jonglant aves les \csname et autre \@nameuse
\newcommand{\umlSaveClass}[3][]{%
\newsavebox{\#2}%
\savebox{\#2}{%
\umlClass[#1]{#2}{#3}%
}%
}
% Pas de \umlUseClass car sera egalement utilis\'ee pour les acteurs, ...
\newcommand{\umlUseBox}[1]{\usebox{\#1}}
% % Surcourche à la commande de dessin de classe :
% %
% % CECI FONCTIONNE PAS :
% % \newsavebox{\csname#2\endcsname} PLANTE :
% % idem avec :
% % \expandafter\newsavebox{\csname#2\endcsname}
% % ! LaTeX Error: Command \csnameClasse 1 bis\endcsname already defined.
% %
% \newcommand{\umlSaveClass}[3][]{%
% \typeout{**************avant newsavebox }
% \expandafter\newsavebox{\csname#2\endcsname}%
% \typeout{**************apres newsavebox }
% \savebox{\csname#2\endcsname}{%
% \typeout{**************apres savebox }
% \umlClass[#1]{#2}{#3}%
% }%
% }
% % Pas de \umlUseClass car sera aussi utilis\'ee pour les acteurs, ...
% \newcommand{\umlUseBox}[1]{%
% \typeout{***************avant use box }
% \usebox{\csname#1\endcsname}%
% }
% % Surcourche à la commande de dessin de classe :
% % CECICOMPILE MAIS FONCTIONNE PAS
% % affiche "Classe 1bisClasse 1bis" (nom double) sous la classe
% \newcommand{\umlSaveClass}[3][]{%
% \newsavebox{\@nameuse{#2}}%
% \savebox{\@nameuse{#2}}{%
% \umlClass[#1]{#2}{#3}%
% }%
% }
% % Pas de \umlUseClass car sera aussi utilis\'ee pour les acteurs, ...
% \newcommand{\umlUseBox}[1]{%
% \usebox{\@nameuse{#1}}%
% }
% % Surcourche à la commande de dessin de classe :
% % CECI FONCTIONNE PAS :
% % ! Illegal parameter number in definition of \@tempa.
% % Je n'ai pas reussi en jonglant aves les \csname et autre \@nameuse
% \newcommand{\umlSaveClass}[3][]{%
% \@namedef{boxname}{#2}
% \newsavebox{\expandafter\boxname}%
% \savebox{\expandafter\boxname}}{%
% \umlClass[#1]{#2}{#3}%
% }%
% }
% % Pas de \umlUseClass car sera aussi utilis\'ee pour les acteurs, ...
% \newcommand{\umlUseBox}[1]{%
% \@namedef{boxname}{#1}
% \usebox{\expandafter\boxname}%
% }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Memorisation d'une classe dans une commande
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% A faire (utiliser gdef par exemple ?)
% s'assurer que la commande cree est GLOGALE !!
% \newcommand{\umlDefClass}[3][]{%
% \@ifundefined{\csname#2\endcsname}{%
% % NOT DEFINE
% \typeout{^^Jcommande NON definie : "#2"^^J}%
% \newcommand{\csname#2\endcsname}{%
% \umlClass[#1]{#2}{#3
% }
% }{%
% % IS DEFINE
% \typeout{^^Jcommande DEJA definie : "#2"^^J}%
% \renewcommand{\csname#2\endcsname}{%
% \umlClass[#1]{#2}{#3
% }
% }
% }
% % Pas de \umlRunClass car sera aussi utilis\'ee pour les acteurs, ...
% \newcommand{\umlRun}[1]{\@usename{#1}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% La macro pour dessiner un acteur :
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\umlActor}[2][]{{%
\psset{unit=0.8,arrows=-}%
\psset{#1}%
\begin{tabular}[t]{c}%
\begin{pspicture}(-0.5,0)(0.5,1.9)%
\psset{linewidth=\umldim@ActorLineWidth}%
\pscircle(0,1.6){0.3\psyunit}% la tete
\psline(0cm,.65)(0cm,1.3)% le tronc
\psline(-0.25,0cm)(0cm,0.65)% jambe gauche
\psline(0.25,0cm)(0cm,0.65)% jambe droite
\psline(-0.5,1)(0.5,1)% les bras
\end{pspicture}\\
\begin{pspicture}(0,0)%
\setlength{\tabcolsep}{0pt}%
\begin{tabular}[t]{c}%
#2%
\end{tabular}%
\end{pspicture}\\
\end{tabular}%
}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% La macro pour dessiner les useCase :
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \umlCase[keyOptions]{Title}{Body} : #2 = Title
% Option : idem que psovalbox
% Remarque : utiliser ovalnode et non pas rnode pour les placements
%
% BUG : \psovalbox creer une boite RECTANGULAIRE dans la quelle il y a
% un oval => difficile de s\'eparer la CREATION du dessin et le PLACEMENT
% de celui-ci avec la cr\'eation d'un node CONCLUSION : inutilis\'e !
% (Utiliser plutot la commande suivante \umlCasePut)
%
\newcommand{\umlCase}[2][]{{%
\psset{#1}% Reading keyOptions
\sbox{\umlbox@out}{\umlStack{#2}}%
\psovalbox{\usebox{\umlbox@out}}
}}
% Pour placer directement dans un ovalnode
% UTILISATION :
% \umlCasePut[keyOptions{10,2}{C6}{Identifier\\contraintes bloquantes}%
%
\newcommand{\umlCasePut}[4][]{{%
\psset{#1}% Reading keyOptions
\rput(#2){\ovalnode[framesep=0]{#3}{\umlStack{#4}}}%
}}
\let\umlPutCase\umlCasePut % for compatibility
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% La macro pour dessiner les etats :
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \umlState[keyOptions]{Title}{Body} : #2 = Title ; #3 = Body
%
\newcommand{\umlState}[3][]{{%
\psset{#1}% Reading keyOptions
% \typeout{***** DEBUT umlState : Titre=:#2:, Body=:#3:}%
\def\next{#2}%
\ifx\next\empty
% \typeout{**Title IS EMPTY : #2}
\sbox{\umlbox@out}{\texttt{\umlStack[umlStackSep=0.35em]{#3}}}%
\else
% \typeout{**Title is NOT EMPTY : #2}%
\def\next{#3}%
\ifx\next\empty
% \typeout{**Body IS EMPTY : #3}%
\sbox{\umlbox@out}{\textbf{\umlStack[umlStackSep=.35em]{#2}}}%
\else
% \typeout{**Body is NOT EMPTY : #3}%
\sbox{\umlbox@out}{\umlStack{%
\textbf{%
\umlStack[umlStackSep=.35em]{#2}%
}\\
\hline%
\texttt{%
\umlStack[umlStackSep=.35em,umlAlign=l]{#3}%
}%\\%
}}%
\fi
\fi
\psframebox[framesep=0,cornersize=absolute,linearc=0.2]%
{\usebox{\umlbox@out}}%
}}
\newcommand{\umlStateIn}[1][]{{%
\psset{#1}% Reading keyOptions
\begin{pspicture}[](-0.25,-0.25)(0.25,0.25)
\pscircle[fillstyle=solid,fillcolor=black]{0.25}%
\end{pspicture}%
}}
\newcommand{\umlStateOut}[1][]{{%
\psset{#1}% Reading keyOptions
\begin{pspicture}[](-0.40,-0.40)(0.40,0.40)
\pscircle[fillstyle=solid,fillcolor=black]{0.25}%
\pscircle[fillstyle=none,linewidth=0.06]{0.40}%
\end{pspicture}%
}}
% Pour placer directement dans un cnode
% UTILISATION :
% \umlPutStateIn[keyOptions]{10,2}{stateInA}%
%
\newcommand{\umlPutStateIn}[3][]{{%
\psset{#1}% Reading keyOptions
\rput(#2){\cnode[linestyle=none]{0.25}{#3}{%
\pscircle[fillstyle=solid,fillcolor=black]{0.25}%
}}%
}}
\newcommand{\umlPutStateOut}[3][]{{%
\psset{#1}% Reading keyOptions
\rput(#2){\cnode[linestyle=none]{0.40}{#3}{%
\pscircle[fillstyle=solid,fillcolor=black]{0.25}%
\pscircle[fillstyle=none,linewidth=0.06]{0.40}%
}}%
}}
% A FAIRE : pour le pseudo-\'etat 'History"
% \newcommand{\umlStateH}[1][]{{%
% \psset{#1}% Reading keyOptions
% }}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% La macro pour dessiner les notes :
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \umlNote[keyOptions]{Body} :
%
\newcommand{\umlNote}[2][]{{%
\psset{umlAlign=l}%
\psset{#1}% Reading keyOptions
\sbox{\umlbox@a}{\texttt{\umlStack[umlStackSep=1.5ex]{#2}}}%
\settowidth{\umldim@W}{\usebox{\umlbox@a}}% Width
\settoheight{\umldim@H}{\usebox{\umlbox@a}}% Height
\settodepth{\umldim@D}{\usebox{\umlbox@a}}% Depth
\setlength{\umldim@a}{\umldim@W - 2.0ex}% Width - coin
\setlength{\umldim@b}{\umldim@H - 2.0ex}% Height - coin
\setlength{\umldim@c}{\umldim@H + \umldim@D}% hauteur totale
\psframe(0,-\umldim@D)(\umldim@W,\umldim@H)%
\psframe[linecolor=white](\umldim@a,\umldim@b)(\umldim@W,\umldim@H)%
% On d\'ecalle le triangle vers l'int\'erieur pour qu'il ne d\'eborde pas :
\setlength{\umldim@W}{\
[email protected]\pslinewidth}%
\setlength{\umldim@H}{\
[email protected]\pslinewidth}%
% \setlength{\umldim@D}{\
[email protected]\pslinewidth}%
\pspolygon(\umldim@W,\umldim@b)%
(\umldim@a,\umldim@H)%
(\umldim@a,\umldim@b)%
(\umldim@W,\umldim@b)%
\usebox{\umlbox@a}%
}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Commandes de placement relatif de type "LOGO"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% A partir d'une version TEX de Denis GIROU
% Inspired by an idea of Sebastian Rahtz <
[email protected]>
% (LGC, example 4-10-10)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% For debug : ShowPosition
%
% usage :
% \ifthenelse{\value{umlDebug} > 0}{\ShowPosition}{}%
%
\newboolean{umlDebug}\setboolean{umlDebug}{false}
\newcommand{\ShowPosition}[1][]{%
\typeout{%
**** umlCpt@Direction=\the\value{umlCpt@Direction} - %
X=\the\X\space - Y=\the\Y^^J%
\space\space\space\space#1^^J%
}%
}%
% Direction (non utilis\'ee pour l'instant) cod\'e en nombre de quart de cercle
% (i x 90) => 0 right, 1 up, 2 left, 3 down
%
\newcounter{umlCpt@Direction}\setcounter{umlCpt@Direction}{-1}
% New length for recording current postion :
\newlength{\umldim@PosX}%\setlength\umldim@PosX{0pt}
\newlength{\umldim@PosY}%\setlength\umldim@PosY{0pt}
% ALIAS for user ?
\newlength{\X}%\setlength\X{\umldim@PosX}
\newlength{\Y}%\setlength\Y{\umldim@PosY}
% Reset position
\newcommand{\ResetXY}{%
\pssetlength{\umldim@PosX}{0}%
\pssetlength{\umldim@PosY}{0}%
\pssetlength{\X}{0}%
\pssetlength{\Y}{0}%
\ifthenelse{\value{umlDebug} > 0}{\ShowPosition}{}%
}
\ResetXY
% % For Getting X or Y position by the user.
% \newcommand{\X}{\the\umldim@PosX}
% \newcommand{\Y}{\the\umldim@PosY}
% Set position
\newcommand{\SetX}[1]{%
\pssetlength{\umldim@PosX}{#1}%
\pssetlength{\X}{#1}%
\ifthenelse{\value{umlDebug} > 0}{\ShowPosition}{}%
}
\newcommand{\SetY}[1]{%
\pssetlength{\umldim@PosY}{#1}%
\pssetlength{\Y}{#1}%
\ifthenelse{\value{umlDebug} > 0}{\ShowPosition}{}%
}
% IMPORTANT : essayer d'utiliser les nodes ou autre
% coordonnees speciales de pstricks pour \SetXY :
% Utilisation de \pst@getcoor et \pssetxlength
\newcommand{\SetXY}[1]{%
\pssetxlength{\umldim@PosX}{#1}%
\pssetylength{\umldim@PosY}{#1}%
\pssetxlength{\X}{#1}%
\pssetylength{\Y}{#1}%
\ifthenelse{\value{umlDebug} > 0}{\ShowPosition}{}%
}
\newcommand{\incrX}[1]{%
% record the direction for later (NOT DONE)
% \setcounter{umlCpt@Direction}{0} % if #1 is positive
% \setcounter{umlCpt@Direction}{3} % if #1 is negative
% increment X position
\psaddtolength{\umldim@PosX}{#1}
\psaddtolength{\X}{#1}
}
\newcommand{\incrY}[1]{%
% record the direction for later (NOT DONE)
% \setcounter{umlCpt@Direction}{1} % if #1 is positive
% \setcounter{umlCpt@Direction}{4} % if #1 is negative
% increment Y position
\psaddtolength{\umldim@PosY}{#1}
\psaddtolength{\Y}{#1}
}
% For moving Est, West, North or Sud
\newcommand{\moveE}[1]{\incrX{#1}}
\newcommand{\moveW}[1]{\incrX{-#1}}
\newcommand{\moveN}[1]{\incrY{#1}}
\newcommand{\moveS}[1]{\incrY{-#1}}
% % % \newcommand{\Right}[1]{%
% % % % record the direction for later
% % % \setcounter{umlCpt@Direction}{0}
% % % % increment X position
% % % \psaddtolength{\umldim@PosX}{#1}
% % % }
% % % \newcommand{\Up}[1]{%
% % % % record the direction for later
% % % \setcounter{umlCpt@Direction}{1}
% % % % increment Y position
% % % \psaddtolength{\umldim@PosY}{#1}
% % % }
% % %
% % % \newcommand{\Left}[1]{%
% % % % record the direction for later
% % % \setcounter{umlCpt@Direction}{2}
% % % % decrement X position
% % % \psaddtolength{\umldim@PosX}{-#1}
% % % }
% % %
% % % \newcommand{\Down}[1]{%
% % % % record the direction for later
% % % \setcounter{umlCpt@Direction}{3}
% % % % decrement Y position
% % % \psaddtolength{\umldim@PosY}{-#1}
% % % }
% % Put an object at current coordinates
% \newcommand{\rputXY}[2][]{%
% \psset{#1}%
% \rput(\umldim@PosX,\umldim@PosY){#2}
% }
%
% Put an object at current coordinates
\newcommand{\rputXY}[2][]{%
\psset{#1}%
\rput(\umldim@PosX,\umldim@PosY){#2}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% D\'efinition des "fleches" de UML (sous forme de labels)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\ncputicon}[2][]{{%
\psset{npos=0,nrot=:D}% defaut : au debut et vers la gauche
\psset{#1}%
\@ifundefined{umlicon@#2}%
{\typeout{^^JERREUR : FLECHE NON definie "#2"^^J}}%
{}% FLECHE BIEN definie
\ncput{\@nameuse{umlicon@#2}}
}}
% Definition des fleches de base (vers la droite)
% Utiliser nrot=:U pour une orientation vers la droite (Up)
% Utiliser nrot=:D pour une orientation vers la gauche (Down)
\newcommand{\umlicon@umlV}{%
\psline(-0.4,0.2)(0,0)(-0.4,-0.2)
}
\newcommand{\umlicon@umlHerit}{%
\pstriangle[gangle=-90,
linestyle=solid,
fillstyle=solid,
fillcolor=white,
](-0.6,0)(0.4,0.6)% (centre)(Width,Length)
}
\newcommand{\umlicon@umlAgreg}{%
\psdiamond[linestyle=solid,
fillstyle=solid,
fillcolor=white,
](-0.25,0)(-0.25,0.15)
}
\newcommand{\umlicon@umlCompos}{%
\psdiamond[linestyle=solid,
fillstyle=solid,
fillcolor=black,
](-0.25,0)(-0.25,0.15)
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Nouvelles d\'efinition pour les interconnexions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Ces connecteurs sont une surcouche aux diff\'erents connecteurs
% propos\'es par pstricks.
% Leur but est de simplifier le trac\'e des liens en se restreingnant aux
% directions horizontales et verticales.
%
% Le principe est d'indiquer dans le nom même de la commande le nombre
% de segments à tracer et leur direction :
% - E, W, N, S pour Est, West, North, Sud
% - H, V pour Horizontal; Vertical
% - D pour diagonal
% - X pour indiff\'erent
% Un seul segments
% Effet de bord : en fait, un deuxieme segment est dessin\'e. Mais celui
% n'apparait g\'en\'eralement pas car il longe la frontière de boite
\newpsobject{ncE}{ncangle}{angleA=0,angleB=180,armB=0,npos=0.5,nodesepB=-0.5pt}
% \newpsobject{ncE}{ncangle}{angleA=0,angleB=180,armB=0,npos=0.5}
\newpsobject{ncW}{ncangle}{angleA=180,angleB=0,armB=0,npos=0.5}
\newpsobject{ncN}{ncangle}{angleA=90,angleB=-90,armB=0,npos=0.5}
\newpsobject{ncS}{ncangle}{angleA=-90,angleB=90,armB=0,npos=0.5}
% Deux segments
\newpsobject{ncEN}{ncangle}{angleA=0,angleB=-90,armB=0}
\newpsobject{ncES}{ncangle}{angleA=0,angleB=90,armB=0}
\newpsobject{ncWN}{ncangle}{angleA=180,angleB=-90,armB=0}
\newpsobject{ncWS}{ncangle}{angleA=180,angleB=90,armB=0}
\newpsobject{ncNE}{ncangle}{angleA=90,angleB=180,armB=0}
\newpsobject{ncNW}{ncangle}{angleA=90,angleB=0,armB=0}
\newpsobject{ncSE}{ncangle}{angleA=-90,angleB=180,armB=0}
\newpsobject{ncSW}{ncangle}{angleA=-90,angleB=0,armB=0}
% Trois segments
% On peut utiliser armA ou armB pour imposer la longueur des extr\'emit\'es
%
% remplace \ncbar (connecteurs en forme de U)
\newpsobject{ncEVW}{ncangles}{angleA=0,angleB=0}
\newpsobject{ncWVE}{ncangles}{angleA=180,angleB=180}
\newpsobject{ncSHN}{ncangles}{angleA=-90,angleB=-90}
\newpsobject{ncNHS}{ncangles}{angleA=90,angleB=90}
% connecteurs en forme de Z (mais \`a angles droits)
\newpsobject{ncEVE}{ncangles}{angleA=0,angleB=180}
\newpsobject{ncWVW}{ncangles}{angleA=180,angleB=0}
\newpsobject{ncNHN}{ncangles}{angleA=90,angleB=-90}
\newpsobject{ncSHS}{ncangles}{angleA=-90,angleB=90}
% connecteurs 3 segments dont segment median en diagonale (incomplet)
\newpsobject{ncEDE}{ncdiag}{angleA=0,angleB=180}
\newpsobject{ncWDW}{ncdiag}{angleA=180,angleB=0}
\newpsobject{ncNDN}{ncdiag}{angleA=90,angleB=-90}
\newpsobject{ncSDS}{ncdiag}{angleA=-90,angleB=90}
% quatre (voire trois) segments :
\newpsobject{ncSXE}{ncangles}{angleA=-90,angleB=180}
\newpsobject{ncSXW}{ncangles}{angleA=-90,angleB=0}
\newpsobject{ncEXS}{ncangles}{angleA=0,angleB=90}
\newpsobject{ncEXN}{ncangles}{angleA=0,angleB=-90}
\newpsobject{ncWXS}{ncangles}{angleA=180,angleB=90}
\newpsobject{ncWXN}{ncangles}{angleA=180,angleB=-90}
\newpsobject{ncNXE}{ncangles}{angleA=90,angleB=180}
\newpsobject{ncNXW}{ncangles}{angleA=90,angleB=0}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% FIN
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\typeout{Package \filename.sty is loaded.}
\endinput