diff options
Diffstat (limited to 'Master/texmf-dist/metapost/metauml/metauml_class.mp')
-rw-r--r-- | Master/texmf-dist/metapost/metauml/metauml_class.mp | 412 |
1 files changed, 258 insertions, 154 deletions
diff --git a/Master/texmf-dist/metapost/metauml/metauml_class.mp b/Master/texmf-dist/metapost/metauml/metauml_class.mp index f99b134c0d4..c3ac333b214 100644 --- a/Master/texmf-dist/metapost/metauml/metauml_class.mp +++ b/Master/texmf-dist/metapost/metauml/metauml_class.mp @@ -1,19 +1,5 @@ -% MetaUML, a MetaPost library for typesetting exquisite UML diagrams. -% Copyright (C) 2005 Ovidiu Gheorghies -% -% This program is free software; you can redistribute it and/or -% modify it under the terms of the GNU General Public License -% as published by the Free Software Foundation; either version 2 -% of the License, or (at your option) any later version. -% -% This program is distributed in the hope that it will be useful, -% but WITHOUT ANY WARRANTY; without even the implied warranty of -% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -% GNU General Public License for more details. -% -% You should have received a copy of the GNU General Public License -% along with this program; if not, write to the Free Software -% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +% Copyright 2005 2015 Ovidiu Gheorghies +% Licensed under the Apache License, Version 2.0. if known _metauml_class_mp: expandafter endinput @@ -24,12 +10,12 @@ _metauml_class_mp:=1; % The guard values (such as _metauml_mp) do ensure that the file isn't loaded multiple times, % but this macro makes sure that MetaPost won't try to load the file and display a message for that. def inputonce text libraryFile= - if not known scantokens ("_" & str libraryFile & "_mp"): - %includeonce% show "Loading " & str libraryFile; - scantokens ("input " & str libraryFile); - else: - %includeonce% show str libraryFile & " already loaded."; - fi; + if not known scantokens ("_" & str libraryFile & "_mp"): + %includeonce% show "Loading " & str libraryFile; + scantokens ("input " & str libraryFile); + else: + %includeonce% show str libraryFile & " already loaded."; + fi; enddef; inputonce metauml_defaults; @@ -39,86 +25,106 @@ inputonce util_picture; inputonce util_picture_stack; inputonce util_shade; -string accessPublic, accessProtected, accessPrivate; -accessPublic:="+"; -accessProtected:="#"; -accessPrivate:="-"; +string visibilityPublic, visibilityProtected, visibilityPrivate, visibilityPackage; +visibilityPublic:="+"; +visibilityProtected:="#"; +visibilityPrivate:="-"; +visibilityPackage:="~"; + +string metauml_private_abstractMarker, metauml_private_staticMarker; +metauml_private_abstractMarker := "@abstract"; +metauml_private_staticMarker := "@static"; + +def abstract expr methodName= metauml_private_abstractMarker&methodName enddef; +def static expr featureName= metauml_private_staticMarker&featureName enddef; + +def metauml_private_isAbstract(expr name) = (substring (0, 9) of name = metauml_private_abstractMarker) enddef; +def metauml_private_isStatic(expr name) = (substring (0, 7) of name = metauml_private_staticMarker) enddef; +def metauml_private_stripStatic(expr name) = substring (7,infinity) of name enddef; +def metauml_private_stripAbstract(expr name) = substring (9,infinity) of name enddef; vardef ClassInfo@#= attributes(@#); - var(numeric) featureAccessSpacing, accessWidth, accessHeight; var(color) foreColor, borderColor; + var(string) featureVisibilityMode; FontInfo.@#nameFont(metauml_defaultFont, defaultscale); - - FontInfo.@#attributeFont (metauml_defaultFont, defaultscale); - FontInfo.@#methodFont (metauml_defaultFont, defaultscale); + FontInfo.@#featureFont (metauml_defaultFont, defaultscale); FontInfo.@#stereotypeFont(metauml_defaultFont, .7); ShadeInfo.@#iShade; - @#featureAccessSpacing := 2; - @#accessWidth := 7; - @#accessHeight := 6.75; + @#featureVisibilityMode := "individual"; % "none", "grouped" @#foreColor := .9white; @#borderColor := black; PictureInfo.@#iName (2, 2, 1, 3)(@#nameFont); + @#iName.ignoreNegativeBase := 1; - PictureInfo.@#iStereotype(2, -5, 2, 2)(@#stereotypeFont); - PictureInfo.@#iAttribute (2, 2, 1.25, 0)(@#attributeFont); - PictureInfo.@#iMethod (2, 2, 1.25, 0)(@#methodFont); + PictureInfoCopy.@#iNameAbstract(@#iName); + @#iNameAbstract.iFont.name := metauml_defaultFontOblique; + + PictureInfo.@#iStereotype(2, 2, 2, 2)(@#stereotypeFont); + @#iStereotypeStack.iPict.ignoreNegativeBase := 1; PictureStackInfo.@#iStereotypeStack(2, 2, 1, 1)(5.5)(@#iStereotype); - PictureStackInfo.@#iAttributeStack (2, 2, 2.5, 2)(10.5)(@#iAttribute); % 8.5 - PictureStackInfo.@#iMethodStack (2, 2, 2.5, 2)(10.5)(@#iMethod); - @#iAttributeStack.iPict.bottom := 2; - %@#iAttributeStack.iPict.boxed := 1; - @#iMethodStack.iPict.bottom := 2; - %@#iMethodStack.iPict.boxed := 1; - LockInfo.@#iLock(@#accessWidth, @#accessHeight, .6, .15, .55, .4white, .6white, .7white, .3white); + PictureInfo.@#iFeature (2, 2, 1.25, 0)(@#featureFont); - @#iName.ignoreNegativeBase := 1; - @#iAttributeStack.iPict.ignoreNegativeBase := 1; - @#iMethodStack.iPict.ignoreNegativeBase := 1; - @#iStereotypeStack.iPict.ignoreNegativeBase := 1; + PictureInfoCopy.@#iFeatureAbstract (@#iFeature); + @#iFeatureAbstract.iFont.name := metauml_defaultFontOblique; + + PictureInfoCopy.@#iFeatureStatic (@#iFeature); + @#iFeatureStatic.textDecoration := "underline"; + + PictureStackInfo.@#iFeatureStack (2, 2, 2.5, 2)(10.5)(@#iFeature); + PictureStackInfoCopy.@#iAttributeStack(@#iFeatureStack); + PictureStackInfoCopy.@#iMethodStack(@#iFeatureStack); + + @#iFeatureStack.iPict.bottom := 2; + @#iFeatureStack.iPict.ignoreNegativeBase := 1; + + PictureStackInfoCopy.@#iAttributeVisibilityStack (@#iFeatureStack); + PictureStackInfoCopy.@#iMethodVisibilityStack (@#iFeatureStack); + + @#iAttributeVisibilityStack.right := 0; + @#iMethodVisibilityStack.right := 0; enddef; vardef ClassInfoCopy@#(text src)= log "ClassInfoCopy: Copying class"; attributes(@#); - var(numeric) featureAccessSpacing, accessWidth, accessHeight; + var(numeric) featureVisibilitySpacing, visibilityWidth, visibilityHeight; var(color) foreColor, borderColor; + var(string) featureVisibilityMode; FontInfoCopy.@#nameFont(src.nameFont); - - FontInfoCopy.@#attributeFont(src.attributeFont); - FontInfoCopy.@#methodFont(src.methodFont); + FontInfoCopy.@#featureFont(src.featureFont); FontInfoCopy.@#stereotypeFont(src.stereotypeFont); ShadeInfoCopy.@#iShade(src.iShade); - @#featureAccessSpacing := src.featureAccessSpacing; - @#accessWidth := src.accessWidth; - @#accessHeight := src.accessHeight; - @#foreColor := src.foreColor; @#borderColor := src.borderColor; - PictureInfoCopy.@#iName (src.iName); + PictureInfoCopy.@#iName (src.iName); + PictureInfoCopy.@#iNameAbstract (src.iNameAbstract); PictureInfoCopy.@#iStereotype(src.iStereotype); - PictureInfoCopy.@#iAttribute (src.iAttribute); - PictureInfoCopy.@#iMethod (src.iMethod); + PictureInfoCopy.@#iFeature (src.iFeature); + PictureInfoCopy.@#iFeatureAbstract (src.iFeatureAbstract); + PictureInfoCopy.@#iFeatureStatic (src.iFeatureStatic); PictureStackInfoCopy.@#iStereotypeStack(src.iStereotypeStack); + PictureStackInfoCopy.@#iFeatureStack (src.iFeatureStack); PictureStackInfoCopy.@#iAttributeStack (src.iAttributeStack); PictureStackInfoCopy.@#iMethodStack (src.iMethodStack); + PictureStackInfoCopy.@#iAttributeVisibilityStack (src.iAttributeVisibilityStack); + PictureStackInfoCopy.@#iMethodVisibilityStack (src.iMethodVisibilityStack); - LockInfoCopy.@#iLock(src.iLock); + @#featureVisibilityMode := src.featureVisibilityMode; enddef; ClassInfo.iClass; @@ -136,7 +142,8 @@ iInterface.iAttributeStack.top := 0; iInterface.iAttributeStack.bottom := 0; iInterface.iName.iFont.name := metauml_defaultFontOblique; -ClassInfoCopy.iAbstractClass(iInterface); +ClassInfoCopy.iAbstractClass(iClass); +iAbstractClass.iName.iFont.name := metauml_defaultFontOblique; % % CLASS @@ -146,19 +153,30 @@ vardef defClass@#(expr pname) = @#className := "Class"; string @#name; - @#name = pname; + boolean @#isAbstract; + + @#isAbstract := metauml_private_isAbstract(pname); + if @#isAbstract: + @#name = metauml_private_stripAbstract(pname); + else: + @#name = pname; + fi numeric @#nStereotypes; string @#stereotypes[]; string @#attributes[]; - string @#attributesAccess[]; + string @#attributesVisibility[]; + boolean @#attributesIsStatic[]; string @#methods[]; - string @#methodsAccess[]; + string @#methodsVisibility[]; + boolean @#methodsIsStatic[]; + boolean @#methodsIsAbstract[]; numeric @#nAttrs; numeric @#nMethods; + numeric @#nStereotypes; @#nStereotypes := 0; @#nAttrs := 0; @@ -166,56 +184,86 @@ vardef defClass@#(expr pname) = enddef; vardef addAttribute@#(expr pcontent) = - string access; - access := substring(0,1) of pcontent; - if (not (access = accessPublic)) and - (not (access = accessPrivate)) and - (not (access = accessProtected)): - - @#.attributes[@#.nAttrs] := pcontent; - @#.attributesAccess[@#.nAttrs] := accessProtected; + string visibility; + string attribute; + + attribute := pcontent; + + @#attributesIsStatic[@#nAttrs] := metauml_private_isStatic(attribute); + if @#attributesIsStatic[@#nAttrs]: + attribute := metauml_private_stripStatic(attribute); + fi + + visibility := substring(0,1) of attribute; + if (not (visibility = visibilityPublic)) and + (not (visibility = visibilityPrivate)) and + (not (visibility = visibilityProtected)) and + (not (visibility = visibilityPackage)): + + @#.attributes[@#.nAttrs] := attribute; + @#.attributesVisibility[@#.nAttrs] := visibilityPackage; else: save from; from := 1; - if (substring(1,2) of pcontent) = " ": from := 2; fi; + if (substring(1,2) of attribute) = " ": from := 2; fi; - @#.attributes[@#.nAttrs] := substring(from, infinity) of pcontent; - @#.attributesAccess[@#.nAttrs] := access; + @#.attributes[@#.nAttrs] := substring(from, infinity) of attribute; + @#.attributesVisibility[@#.nAttrs] := visibility; fi; @#.nAttrs := @#.nAttrs + 1; enddef; vardef addMethod@#(expr pcontent) = - string access; - access := substring(0,1) of pcontent; - if (not (access = accessPublic)) and - (not (access = accessPrivate)) and - (not (access = accessProtected)): - - @#.methods[@#.nMethods] := pcontent; - @#.methodsAccess[@#.nMethods] := accessProtected; + string visibility; + string method; + + method := pcontent; + + @#methodsIsStatic[@#nMethods] := metauml_private_isStatic(method); + if @#methodsIsStatic[@#nMethods]: + method := metauml_private_stripStatic(method); + fi + + @#methodsIsAbstract[@#nMethods] := metauml_private_isAbstract(method); + if @#methodsIsAbstract[@#nMethods]: + method := metauml_private_stripAbstract(method); + @#isAbstract := true; + fi + + visibility := substring(0,1) of method; + if (not (visibility = visibilityPublic)) and + (not (visibility = visibilityPrivate)) and + (not (visibility = visibilityProtected)) and + (not (visibility = visibilityPackage)): + + @#.methods[@#.nMethods] := method; + @#.methodsVisibility[@#.nMethods] := visibilityPackage; else: - @#.methods[@#.nMethods] := substring(1, 999) of pcontent; - @#.methodsAccess[@#.nMethods] := access; + save from; + from := 1; + if (substring(1,2) of method) = " ": from := 2; fi; + + @#.methods[@#.nMethods] := substring(from, infinity) of method; + @#.methodsVisibility[@#.nMethods] := visibility; fi; @#.nMethods := @#.nMethods + 1; enddef; vardef classStereotype@#(expr pcontent) = - @#stereotypes[@#nStereotypes] := pcontent; - @#nStereotypes := @#nStereotypes + 1; + show "Macro classStereotype is deprecated, use Class_stereotypes instead."; + Class_stereotypes.@#(pcontent); enddef; vardef classStereotypes@#(text stereotypes)= - for stereotype = stereotypes: - classStereotype@#(stereotype); - endfor; + show "Macro classStereotypes is deprecated, use Class_stereotypes instead."; + Class_stereotypes.@#(stereotypes); enddef; vardef EClass@#(text _info)(expr name)(text attributes)(text methods)= log "EClass begin: " & str @#; + defClass@#(name); log "Copying class info"; @@ -263,87 +311,126 @@ vardef Class_border@#= objectBox(@#) enddef; +vardef Class_noVisibilityMarkers@#= + @#info.featureVisibilityMode := "none"; +enddef; + vardef Class_layout@# = - if @#layedout = 1: + if @#laidout = 1: log "Class " & (str @#) & " has already been layed out"; else: - @#layedout := 1; + @#laidout := 1; log "Class layout: " & (str @#); - @#maxFeatureWidth := 0; - EPictureStack.@#stereotypeStack(@#info.iStereotypeStack) (scantokens listArray(@#stereotypes)(@#nStereotypes))("vcenterbase"); - EPicture.@#namePict(@#info.iName)(@#name); + if (@#isAbstract): + EPicture.@#namePict(@#info.iNameAbstract)(@#name); + else: + EPicture.@#namePict(@#info.iName)(@#name); + fi; + + layoutObjects(@#stereotypeStack, @#namePict); + + % Define attributes + + def metauml_private_attributeStyleSupplier(expr i)= + if @#attributesIsStatic[i]: @#info.iFeatureStatic + else: @#info.iFeature + fi + enddef; + + @#info.iAttributeStack.childStyleSupplier := "metauml_private_attributeStyleSupplier"; + EPictureStack.@#attributeStack(@#info.iAttributeStack) (scantokens listArray(@#attributes)(@#nAttrs))("vleftbase"); + + if @#info.featureVisibilityMode = "individual": + vardef joinCallbackAttributesVisibility@#= + setObjectJoin(pb.bottom = @#.attributeStack.pict[index].bottom; pb.midx = pa.midx); + setObjectJoinFirst(pa.bottom = @#.attributeStack.pict[index].bottom); + enddef; + + EPictureStack.@#attributeVisibilityStack(@#info.iAttributeVisibilityStack) + (scantokens listArray(@#attributesVisibility)(@#nAttrs)) + ("joinCallbackAttributesVisibility." & (str @#)); + elseif @#info.featureVisibilityMode = "none": + EPicture.@#attributeVisibilityStack(iPictNoMargins)(""); + else: + show "Unknown feature visibility mode", @#featureVisibilityMode; + 1=2; + fi; + + % Define methods + + def metauml_private_methodStyleSupplier(expr i)= + if @#methodsIsStatic[i]: @#info.iFeatureStatic + elseif @#methodsIsAbstract[i]: @#info.iFeatureAbstract + else: @#info.iFeature + fi + enddef; + + @#info.iMethodStack.childStyleSupplier := "metauml_private_methodStyleSupplier"; + EPictureStack.@#methodStack(@#info.iMethodStack) (scantokens listArray(@#methods)(@#nMethods))("vleftbase"); - layoutObjects(@#stereotypeStack, @#namePict, @#attributeStack, @#methodStack); + if @#info.featureVisibilityMode = "individual": + vardef joinCallbackMethodsVisibility@#= + setObjectJoin(pb.bottom = @#.methodStack.pict[index].bottom; pb.midx = pa.midx); + setObjectJoinFirst(pa.bottom = @#.methodStack.pict[index].bottom); + enddef; + + EPictureStack.@#methodVisibilityStack(@#info.iMethodVisibilityStack) + (scantokens listArray(@#methodsVisibility)(@#nMethods)) + ("joinCallbackMethodsVisibility." & (str @#)); + elseif @#info.featureVisibilityMode = "none": + EPicture.@#methodVisibilityStack(iPictNoMargins)(""); + else: + show "Unknown feature visibility mode", @#featureVisibilityMode; + 1=2; + fi; + + % Integrate components + show layoutObjects(@#attributeStack, @#methodStack); + layoutObjects(@#attributeStack, @#methodStack); + + @#attributeStack.left = @#methodStack.left; + @#methodStack.top = @#attributeStack.bottom; - log "Computing maxFeatureWidth"; - log @#stereotypeStack.width; - log @#namePict.width; - log @#attributeStack.width; - log @#methodStack.width; - log "..."; - @#maxFeatureWidth := lmax(@#stereotypeStack.width, @#namePict.width, - @#attributeStack.width, @#methodStack.width); - log "Done computing maxFeatureWidth"; + layoutObjects(@#attributeVisibilityStack, @#methodVisibilityStack); - log "max feature width: " & decimal @#maxFeatureWidth; + @#attributeVisibilityStack.midx = @#methodVisibilityStack.midx; - @#namePict.midx = @#midx; - @#stereotypeStack.midx = @#namePict.midx; + if (@#.nMethods = 0) or (@#info.featureVisibilityMode="none"): + @#methodVisibilityStack.top = @#methodStack.top; + fi; + if (@#.nAttrs = 0) or (@#info.featureVisibilityMode="none"): + @#attributeVisibilityStack.top = @#attributeStack.top; + fi; - @#stereotypeStack.top = @#top; - @#namePict.top = @#stereotypeStack.bottom; - @#attributeStack.top = @#namePict.bottom; - @#methodStack.top = @#attributeStack.bottom; + EGroup.@#visibilityStacks(iGroupNoMargins)(@#attributeVisibilityStack, @#methodVisibilityStack); + + EGroup.@#featureStacks(iGroupNoMargins)(@#attributeStack, @#methodStack); - @#attributeStack.left = @#methodStack.left = - @#left + @#info.accessWidth + @#info.featureAccessSpacing; + layoutObjects(@#visibilityStacks, @#featureStacks); - @#width = @#maxFeatureWidth + @#info.accessWidth + @#info.featureAccessSpacing; - @#bottom = @#methodStack.bottom; + @#visibilityStacks.right = @#featureStacks.left; - log "Class layout done..."; - fi; -enddef; - -vardef Class_paintAccess@#(expr _access, _se) = - save lock; - ELock.lock(@#info.iLock)(_access); - lock.se = _se; - drawObject(lock); -enddef; + EGroup.@#featureGroup(iGroupNoMargins)(@#visibilityStacks, @#featureStacks); -vardef Class_drawFeatures@#= - log "Drawing stereotypes"; - drawObject(@#stereotypeStack); + topToBottom(0)(@#stereotypeStack, @#namePict, @#featureGroup); - log "Drawing name"; - drawObject(@#namePict); - log "Drawing attribute stack"; - drawObject(@#attributeStack); + EGroup.@#all(iGroupNoMargins)(@#stereotypeStack, @#namePict, @#featureGroup); - log "Drawing method stack"; - drawObject(@#methodStack); + layoutObjects(@#all); - log "********************************** Drawing access locks"; - for i = 0 upto @#nAttrs-1: - log @#attributesAccess[i]; - Class_paintAccess@#(@#attributesAccess[i], - @#attributeStack.pict[i].sw + (-@#info.featureAccessSpacing, @#info.iAttributeStack.iPict.bottom)); - endfor; + @#.nw = @#all.nw; + @#.se = @#all.se; - for i = 0 upto @#nMethods-1: - log @#methodsAccess[i]; - Class_paintAccess@#(@#methodsAccess[i], - @#methodStack.pict[i].sw + (-@#info.featureAccessSpacing, @#info.iMethodStack.iPict.bottom)); - endfor; + log "Class layout for " & (str @#) & " done..."; + fi; enddef; vardef Class_paintSkin@# = @@ -351,31 +438,48 @@ vardef Class_paintSkin@# = nameAttributeY := @#attributeStack.top; attributeMethodY := @#methodStack.top; - %fill Class_border.@# shifted (@#info.shade,-@#info.shade) - % withcolor .7white withpen currentpen scaled 1; - drawObjectShade(@#); + drawObjectShade(@#); - fill Class_border.@# withcolor @#info.foreColor; - draw Class_border.@# withcolor @#info.borderColor; + fill Class_border.@# withcolor @#info.foreColor; + draw Class_border.@# withcolor @#info.borderColor; - draw (xpart @#nw, nameAttributeY)--(xpart @#se, nameAttributeY) withcolor @#info.borderColor; - draw (xpart @#nw, attributeMethodY)--(xpart @#se, attributeMethodY) withcolor @#info.borderColor; + draw (xpart @#nw, nameAttributeY)--(xpart @#se, nameAttributeY) withcolor @#info.borderColor; + draw (xpart @#nw, attributeMethodY)--(xpart @#se, attributeMethodY) withcolor @#info.borderColor; enddef; vardef Class_draw@#= - log "draw class begin..."; + log "Class_draw begin " & @#; Class_layout.@#; objectEnsurePositioning.@#; Class_paintSkin.@#; - Class_drawFeatures.@#; + + drawObjects(@#all); + log "Class_draw end " & @#; enddef; vardef Class_setDebugMode@#= @#.info.iName.boxed := 1; + + @#.info.iFeature.boxed := 1; + @#.info.iFeatureStatic.boxed := 1; + @#.info.iFeatureAbstract.boxed := 1; + @#.info.iStereotypeStack.boxed := 1; @#.info.iStereotypeStack.iPict.boxed := 1; @#.info.iAttributeStack.boxed := 1; @#.info.iAttributeStack.iPict.boxed := 1; @#.info.iMethodStack.boxed := 1; @#.info.iMethodStack.iPict.boxed := 1; + + @#.info.iAttributeVisibilityStack.boxed := 1; + @#.info.iAttributeVisibilityStack.iPict.boxed := 1; + @#.info.iMethodVisibilityStack.boxed := 1; + @#.info.iMethodVisibilityStack.iPict.boxed := 1; +enddef; + +vardef Class_stereotypes@#(text _stereotypes)= + for stereotype = _stereotypes: + @#stereotypes[@#nStereotypes] := stereotype; + @#nStereotypes := @#nStereotypes + 1; + endfor; enddef; |